package com.alibaba.citrus.cr.forecast.functions.forecastorder.entity;

import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.model.ApiContext;
import com.alibaba.citrus.cr.common.util.CalendarCompareUtil;
import com.alibaba.citrus.cr.common.util.SpringContextUtil;
import com.alibaba.citrus.cr.forecast.common.LogUtils;
import com.alibaba.citrus.cr.forecast.functions.forecastorder.ability.PriceQueryUtils;
import com.alibaba.citrus.cr.forecast.functions.forecastorder.constants.ForecastConstants;
import com.alibaba.citrus.cr.forecast.repository.*;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.db.service.CustomSequenceAccessor;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.alibaba.lattice2.epoch.user.dto.LoginUser;
import com.alibaba.lattice2.epoch.user.service.EpochLoginUserService;
import com.epoch.app.bcorder.forecast_sales.ForecastOrderTag;
import com.epoch.app.bcorder.model.dto.EmployeeGetCurrentLoginResponse;
import com.epoch.app.bcorder.model.dto.QueryWarehouseByIdRequest;
import com.epoch.app.bcorder.model.dto.SearchScItemByDBWhenDegradedRequest;
import com.epoch.app.bcorder.model.dto.WarehouseInfo;
import com.epoch.app.bcorder.platform_enhance.SaleOrderTag;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.BcOrderService;
import com.epoch.app.bcorder.service.UnifiedInventoryService;
import com.epoch.app.crforecastsales.api.forecastorderlinequery.service.ForecastOrderLineQueryService;
import com.epoch.app.crforecastsales.api.forecastorderwrite.dto.DeleteActivityForecastRequest;
import com.epoch.app.crforecastsales.api.forecastorderwrite.service.ForecastOrderWriteService;
import com.epoch.app.crforecastsales.domian.activitytitle.dto.QueryActivityTitleByActivityIdRequest;
import com.epoch.app.crforecastsales.domian.activitytitle.service.ActivityTitleService;
import com.epoch.app.crforecastsales.domian.activitytitleext.model.ActivityTitleExt;
import com.epoch.app.crforecastsales.domian.activitytitleext.service.ActivityTitleExtService;
import com.epoch.app.crforecastsales.domian.deallinequeue.model.DealLineQueue;
import com.epoch.app.crforecastsales.dto.request.ConfirmForecastRequest;
import com.epoch.app.crforecastsales.dto.response.ConfirmForecastResponse;
import com.epoch.app.crforecastsales.enums.ForecastLineStatusEnum;
import com.epoch.app.crforecastsales.enums.ForecastStatusEnum;
import com.epoch.app.crforecastsales.model.dto.*;
import com.epoch.app.crforecastsales.model.enums.ForecastDealStatusSEO;
import com.epoch.app.crforecastsales.model.enums.ForecastDealTypeSEO;
import com.epoch.app.crforecastsales.model.enums.ForecastOrderLogEnum;
import com.epoch.app.crforecastsales.sdo.ForecastOrderLineSDO;
import com.epoch.app.crforecastsales.sdo.ForecastOrderSDO;
import com.epoch.app.crplatformenhance.api.scitemquery.service.ScItemQueryService;
import com.epoch.app.crplatformenhance.api.strategyquery.service.StrategyQueryService;
import com.epoch.app.crplatformenhance.domain.scitemunit.dto.ScItemUnitLoadListRequest;
import com.epoch.app.crplatformenhance.domain.scitemunit.model.ScItemUnit;
import com.epoch.app.crplatformenhance.domain.scitemunit.service.ScItemUnitService;
import com.epoch.app.crplatformenhance.dto.request.IdQueryRequest;
import com.epoch.app.crplatformenhance.enums.DimensionTypeEnum;
import com.epoch.app.crplatformenhance.enums.StrategyTypeEnum;
import com.epoch.app.crplatformenhance.inventoryallotlinewrite.dto.ReleaseAndDeductRequest;
import com.epoch.app.crplatformenhance.inventoryallotlinewrite.service.InventoryAllotLineWriteService;
import com.epoch.app.crplatformenhance.inventoryallotquery.service.InventoryAllotQueryService;
import com.epoch.app.crplatformenhance.model.dto.*;
import com.epoch.app.crplatformenhance.model.enums.RuleTypeEnum;
import com.epoch.app.crplatformenhance.sdo.DimensionSDO;
import com.epoch.app.crplatformenhance.sdo.StrategySDO;
import com.epoch.app.crpricecenter.api.activityquery.service.ActivityQueryService;
import com.epoch.app.crpricecenter.api.activitywrite.service.ActivityWriteService;
import com.epoch.app.crpricecenter.dto.request.*;
import com.epoch.app.crpricecenter.dto.response.ActivityInfoResponse;
import com.epoch.app.crpricecenter.dto.response.ActivityTermResponse;
import com.epoch.app.crpricecenter.dto.response.ParticipateActivityInfoResponse;
import com.epoch.app.crpricecenter.dto.response.ParticipateInActivityResponse;
import com.epoch.app.crpricecenter.model.dto.ActivityResponse;
import com.epoch.app.crpricecenter.model.dto.ParticipateActivityRequest;
import com.epoch.app.crpricecenter.model.dto.QueryActivityRequest;
import com.epoch.app.crpricecenter.model.enums.ActivityTypeEnum;
import com.epoch.app.crunifiedinventory.api.allocateorderwrite.service.AllocateOrderWriteService;
import com.epoch.app.crunifiedinventory.dto.request.AllocateOrderManualCreateRequest;
import com.epoch.app.crunifiedinventory.dto.request.AllocateOrderSaveRequest;
import com.epoch.app.crunifiedinventory.dto.response.AllocateOrderResponse;
import com.epoch.app.crunifiedinventory.dto.response.AllocateOrderSaveResponse;
import com.epoch.app.crunifiedinventory.model.dto.AllocateOrderScItemDetail;
import com.epoch.app.crunifiedinventory.service.CrUnifiedInventoryService;
import lombok.Getter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author qianlei
 */
@Getter
public class ForecastOrderEntity {
    private static final Log log = Log.getLogger(ForecastOrderEntity.class);
    private ForecastOrderSDO forecastOrderSDO;

    public static final String ALLOTLINEID = "allotlineid";
    public static final String DISINTEGRATION_QTY = "disintegrationQty";
    private static Integer pageSize = 2000;


    private static ActivityQueryService activityQueryService = SpringContextUtil.getBean(ActivityQueryService.class);
    private static AllocateOrderWriteService allocateOrderWriteService = SpringContextUtil.getBean(AllocateOrderWriteService.class);
    private static StrategyQueryService strategyQueryService = SpringContextUtil.getBean(StrategyQueryService.class);
    private static ActivityWriteService activityWriteService = SpringContextUtil.getBean(ActivityWriteService.class);
    private static CustomSequenceAccessor customSequenceAccessor = SpringContextUtil.getBean(CustomSequenceAccessor.class);
    private static ScItemQueryService scItemQueryService = SpringContextUtil.getBean(ScItemQueryService.class);
    private static ForecastOrderWriteService forecastOrderWriteService = SpringContextUtil.getBean(ForecastOrderWriteService.class);
    private static ScItemUnitService scItemUnitService = SpringContextUtil.getBean(ScItemUnitService.class);
    private static PriceQueryUtils priceQueryUtils = SpringContextUtil.getBean(PriceQueryUtils.class);
    private static UnifiedInventoryService unifiedInventoryService = SpringContextUtil.getBean(UnifiedInventoryService.class);
    private static EpochLoginUserService epochLoginUserService;
    //处理队列写
    private static DealLineWriteRepository dealLineWriteRepository;
    //处理队列读
    private static DealLineQueryRepository dealLineQueryRepository;
    //主单读
    private static ForecastOrderQueryRepository forecastOrderQueryRepository;
    //主单写
    private static ForecastOrderWriteRepository forecastOrderWriteRepository;
    //子订单写
    private static ForecastOrderLineWriteRepository forecastOrderLineWriteRepository;
    //子订单读
    private static ForecastOrderLineQueryRepository forecastOrderLineQueryRepository;

    private static InventoryAllotQueryService inventoryAllotQueryService;

    private static InventoryAllotLineWriteService inventoryAllotLineWriteService;
    private static BcOrderService bcOrderService;
    private static ActivityTitleExtService activityTitleExtService;
    private static ActivityTitleService activityTitleService;
    private static CrUnifiedInventoryService crUnifiedInventoryService;
    private static ForecastOrderLineQueryService forecastOrderLineQueryService;
    private static BaseDataService baseDataService;

    static {
        dealLineWriteRepository = SpringContextUtil.getBean(DealLineWriteRepository.class);
        forecastOrderQueryRepository = SpringContextUtil.getBean(ForecastOrderQueryRepository.class);
        dealLineQueryRepository = SpringContextUtil.getBean(DealLineQueryRepository.class);
        forecastOrderWriteRepository = SpringContextUtil.getBean(ForecastOrderWriteRepository.class);
        forecastOrderLineWriteRepository = SpringContextUtil.getBean(ForecastOrderLineWriteRepository.class);
        forecastOrderLineQueryRepository = SpringContextUtil.getBean(ForecastOrderLineQueryRepository.class);
        inventoryAllotQueryService = SpringContextUtil.getBean(InventoryAllotQueryService.class);
        inventoryAllotLineWriteService = SpringContextUtil.getBean(InventoryAllotLineWriteService.class);
        bcOrderService = SpringContextUtil.getBean(BcOrderService.class);
        epochLoginUserService = SpringContextUtil.getBean(EpochLoginUserService.class);
        activityTitleExtService = SpringContextUtil.getBean(ActivityTitleExtService.class);
        activityTitleService = SpringContextUtil.getBean(ActivityTitleService.class);
        crUnifiedInventoryService = SpringContextUtil.getBean(CrUnifiedInventoryService.class);
        forecastOrderLineQueryService = SpringContextUtil.getBean(ForecastOrderLineQueryService.class);
        baseDataService = SpringContextUtil.getBean(BaseDataService.class);

    }

    /**
     * 内外码转换 key
     */
    private static String CODE_FLAG = "codeFlag";
    /**
     * 内外码转换 value
     */
    private static String INNER_CODE_TO_OUT_CODE = "inner_code_to_out_code";
    private static String OUT_CODE_TO_INNER_CODE = "out_code_to_inner_code";
    /**
     * 添加活动查询参数
     */
    private static String ADD_ACTIVITY_QUERY_PARAM = "addActivityQueryParam";
    /**
     * 预报订单号
     */
    private static String FORECAST_ORDER_BIZ_ID = "forecastOrderBizId";
    /**
     * 行号
     */
    private static String SERIAL_NUMBER = "serialNumber";
    /**
     * 时候计算活动金额
     */
    private static String ACTIVITY_GIFT_HAVE_FEE = "activityGiftHaveFee";
    /**
     * 来源系统
     */
    private static String OS = "os";

    private static String INVENTORY_CHECK_FAIL = "库存不足不可以生成销售订单！";

    private static String ACTIVITY_OCCUPY_EXCEPTION = "异常情况活动占用失败！";

    public static ForecastOrderEntity of(ForecastOrderSDO forecastOrderSDO) {
        ForecastOrderEntity forecastEntity = new ForecastOrderEntity();
        forecastEntity.forecastOrderSDO = forecastOrderSDO;
        return forecastEntity;
    }

    /*
        创建并保存预报单 王成
     */
    public String save() {
        LoginUser loginUser = epochLoginUserService.getLoginUser();
        String orderId = "";
//        isBack = false;
        //判断当前状态是否可以提交
        if ((!ForecastStatusEnum.DRAFT.getNumValue().equals(forecastOrderSDO.getStatus())
                && ForecastStatusEnum.PARTIAL_REPLY.getNumValue().equals(forecastOrderSDO.getStatus()))) {
            throw new FunctionException("OTS-04-001-00-15-017");
        }
//        this.forecastOrderSDO.setStatus(1);//设置位为草稿状态
        if (StringUtils.isEmpty(forecastOrderSDO.getId())) {
            // 保存预报主单
            //判断是否有主单id 没有先创建主单 有主单id 就设置子单的mainOrderId 创建子单
            String nextStringSequence = customSequenceAccessor.getNextStringSequence("cr_forecast_sales", "forecastOrderId");
            forecastOrderSDO.setOrderBizId(nextStringSequence);
            forecastOrderSDO.setCreatorName(forecastOrderSDO.getModifierName());
            forecastOrderSDO.setCreatorId(forecastOrderSDO.getModifierId());
            //设置位为草稿状态
            forecastOrderSDO.setStatus(ForecastStatusEnum.DRAFT.getNumValue());
            orderId = forecastOrderWriteRepository.save(this.forecastOrderSDO);
            forecastOrderSDO.setId(orderId);
            LogUtils.printOperateLog(forecastOrderSDO, ForecastOrderLogEnum.CREATE.getForecastOrderLogValue(), "创建预报订单", loginUser);

        } else {//有主单id
            //DB查询预报主单
            ForecastOrderSDO dbForecastOrderSDO = forecastOrderQueryRepository.queyrDetail(forecastOrderSDO.getId());

            //DB状态为已完成的，不允许再编辑保存子单
            if (ForecastStatusEnum.COMPLETED.getNumValue().equals(dbForecastOrderSDO.getStatus())
                    ||ForecastStatusEnum.CANCELLED.getNumValue().equals(dbForecastOrderSDO.getStatus())){
                throw new FunctionException("OTS-04-001-00-15-056");
            }
            //获取当前登录人信息
            EmployeeGetCurrentLoginResponse currentLoginResponse = bcOrderService.employeeGetCurrentLogin();

            if (ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue().equals(forecastOrderSDO.getStatus()) && (currentLoginResponse.getOnlySales() || currentLoginResponse.getIsCustomer())) {
                //如果是业务员 不允许编辑生效时间
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                String inputValidTime = simpleDateFormat.format(forecastOrderSDO.getVaildBeginTime());
                String existValidTime = simpleDateFormat.format(dbForecastOrderSDO.getVaildBeginTime());
                if (!inputValidTime.equals(existValidTime)) {
                    throw new FunctionException("OTS-04-001-00-15-054");
                }
            }
            //待回复状态的保存需要效验有效性策略 20220217需求 待回复状态可以编辑(add by myw) 只有业务员角色才效验待回复状态的有效性检查
            if (ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue().equals(forecastOrderSDO.getStatus()) && currentLoginResponse.getOnlySales()) {
                InvalidStrategyProcess();
            }
            // todo   预报单乐观锁版本控制

            this.forecastOrderSDO.setOrderBizId(dbForecastOrderSDO.getOrderBizId());
            forecastOrderWriteRepository.modify(this.forecastOrderSDO);
            LogUtils.printOperateLog(this.forecastOrderSDO, ForecastOrderLogEnum.EDIT.getForecastOrderLogValue(), "编辑预报订单", loginUser);
            Integer num = 0;//行号
            //根据scitemId去重,防止stream打乱顺序 使用list loop
            List<ForecastOrderLineSDO> forecastOrderLineSDOList = forecastOrderSDO.getForecastOrderLineSDOList();
            for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                if (forecastOrderLineSDO.getUnitPrice() == null) {
                    throw new FunctionException("OTS-04-001-00-15-022");
                }
                //判断单价价格是否有负值
                if (ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue().equals(forecastOrderSDO.getStatus())) {
                    if (forecastOrderLineSDO.getUnitPrice() < 0L) {
                        throw new FunctionException("OTS-04-001-00-15-022");
                    }
                }

                // todo 价格校验按0303需求，后移至预报单提交
                //判断是不是新增的子单 老的子单更新 新的子单创建
                if (null != forecastOrderLineSDO.getId()) {
                    //add by myw,适配小程序传递过来features无值，影响每日库存分解回补和重新占用
                    Long orderLineId = forecastOrderLineSDO.getId();
                    ForecastOrderLineSDO queryOrderLine = forecastOrderLineQueryRepository.query(String.valueOf(orderLineId));
                    Map originLineFeature = forecastOrderLineSDO.getFeatures();
                    Map lineFeatures = queryOrderLine.getFeatures();
                    //接口新增扩展内容需要赋值
                    if (MapUtils.isNotEmpty(lineFeatures)&&MapUtils.isNotEmpty(originLineFeature)){
                        lineFeatures.putAll(originLineFeature);
                    }

                    forecastOrderLineSDO.setFeatures(lineFeatures);
                    Integer realDeductQuantity = 0;
                    if (ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue().equals(forecastOrderSDO.getStatus())) {
                        Map features = forecastOrderLineSDO.getFeatures();
                        if (MapUtils.isNotEmpty(features)
                                && Objects.nonNull(features.get(ALLOTLINEID))
                                && StringUtils.isNotBlank(String.valueOf(features.get(ALLOTLINEID)))
                                && Objects.nonNull(features.get(DISINTEGRATION_QTY))

                        ) {
                            ReleaseAndDeductRequest releaseAndDeductRequest = new ReleaseAndDeductRequest();
                            releaseAndDeductRequest.setAllotLineId(String.valueOf(features.get(ALLOTLINEID)));
                            releaseAndDeductRequest.setOldDeductQuantity(String.valueOf(features.get(DISINTEGRATION_QTY)));
                            releaseAndDeductRequest.setNewDeductQuantity(forecastOrderLineSDO.getQuantity());
                            Result<DailyInventoryDeductResponse> releaseAndDeduct = inventoryAllotLineWriteService.releaseAndDeduct(releaseAndDeductRequest);
                            if (Objects.isNull(releaseAndDeduct) || !releaseAndDeduct.isSuccess()) {
                                throw new FunctionException("OTS-04-001-00-15-053", "待回复状态释放并重新扣减每日库存失败!");
                            }
                            realDeductQuantity = new BigDecimal(releaseAndDeduct.getResult().getRealDeductQuantity()).intValue();
                            // features.put(DISINTEGRATION_QTY,realDeductQuantity);

                        }
                    }
                    if (ForecastStatusEnum.DRAFT.getNumValue().equals(forecastOrderSDO.getStatus())) {
                        verifyDailyInv(forecastOrderLineSDO);
                    }
                    modifyForecastOrderLine(forecastOrderLineSDO, realDeductQuantity);
                } else {
                    if (ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue().equals(forecastOrderSDO.getStatus())) {
                        queryAndDeduct(forecastOrderLineSDO);
                    }

                    if (ForecastStatusEnum.DRAFT.getNumValue().equals(forecastOrderSDO.getStatus())) {
                        verifyDailyInv(forecastOrderLineSDO);
                    }

                    num = addForecastOrderLine(num, forecastOrderLineSDO);

                }
            }
            orderId = forecastOrderSDO.getId();
        }
        return orderId;
    }

    private void InvalidStrategyProcess() {
        //判断待回复状态的订单是否可以保存
        //根据查询结果 判断是时间段还是截止时间 是拦截还是提示
        //如果是拦截的话不允许保存  提示的话可以保存
        MoreConditionQueryRequest moreConditionQueryRequest = new MoreConditionQueryRequest();
        moreConditionQueryRequest.setStrategyType(StrategyTypeEnum.VALIDITY.getCode());
        moreConditionQueryRequest.setOrganizationCode(forecastOrderSDO.getOrganizationCode());//forecastOrderSDO.getOrganizationCode()
        moreConditionQueryRequest.setChannelCode(forecastOrderSDO.getChannelCode());//forecastOrderSDO.getChannelCode()
        moreConditionQueryRequest.setWareHouseCode(forecastOrderSDO.getWareHouseCode());
        log.info("ForecastOrderEntity|save|" + forecastOrderSDO.getOrderBizId() + "|查询有效期校验|request|", JSONObject.toJSONString(moreConditionQueryRequest));
        Result<MoreConditionQueryResponse> moreConditionQueryResponseResult = strategyQueryService.moreConditionQuery(moreConditionQueryRequest);
        log.info("ForecastOrderEntity|save|" + forecastOrderSDO.getOrderBizId() + "|查询有效期校验|result|", JSONObject.toJSONString(moreConditionQueryResponseResult));
        MoreConditionQueryResponse moreConditionQueryResponse = moreConditionQueryResponseResult.getResult();

        if (Objects.nonNull(moreConditionQueryResponse)) {
            StrategySDO strategySDO = moreConditionQueryResponse.getStrategySDO();
            List<DimensionSDO> dimensionSDOList = strategySDO.getDimensionSDOList();
            DimensionSDO dimensionSDO = dimensionSDOList.get(0);
            //获取规则
            String value = dimensionSDO.getRuleName();
            if (StringUtils.equals(RuleTypeEnum.TIME_POINT.getCode(), value)) {
                //获取规则值
                String ruleValue = dimensionSDO.getRuleValue();
                //判断截止时间是否满足 当前时间大于截止时间 不满足
                boolean compare = CalendarCompareUtil.compareDateTimes(null, ruleValue);
                if (compare) {
                    Boolean executeAction = dimensionSDO.getExecuteAction();
                    if (executeAction) {
                        throw new FunctionException("OTS-04-001-00-15-048", "该时间范围内不允许修改，请联系订单员修改");
                        // return "该时间范围内不允许修改，请联系订单员修改";
                    }
                }
            }
            if (StringUtils.equals(RuleTypeEnum.TIME_FRAME.getCode(), value)) {
                String ruleValue = dimensionSDO.getRuleValue();
                //String substring = ruleValue.substring(ruleValue.indexOf("[") + 1, ruleValue.indexOf("]") - 1).replace("\"", "");
                String substring = ruleValue.substring(ruleValue.indexOf("[") + 1, ruleValue.indexOf("]")).replace("\"", "");
                String[] split = substring.split(",");
/*String ruleValueSplit = split[0].split(" ")[1];
String ruleValueSplit1 = split[1].split(" ")[1];*/

                String ruleValueSplit = split[0];
                String ruleValueSplit1 = split[1];
                boolean compareDateTimes = CalendarCompareUtil.compareDateTimes(ruleValueSplit, ruleValueSplit1);
                //如果为true满足可以提交
                if (!compareDateTimes) {
                    Boolean executeAction = dimensionSDO.getExecuteAction();
                    if (executeAction) {
                        throw new FunctionException("OTS-04-001-00-15-048", "该时间范围内不允许修改，请联系订单员修改");
                        // return "该时间范围内不允许修改，请联系订单员修改";
                    }
                }
            }
        }
    }

    private void verifyDailyInv(ForecastOrderLineSDO forecastOrderLineSDO) {
        Map<String, Object> dailyInventory = queryDailyInv(forecastOrderSDO, forecastOrderLineSDO);
        if ((boolean) dailyInventory.getOrDefault("limitSwitch", false)) {
            if (StringUtils.isNotBlank(String.valueOf(dailyInventory.get("dailyInventory")))) {
                BigDecimal existInventory = new BigDecimal(String.valueOf(dailyInventory.get("dailyInventory"))).setScale(3, RoundingMode.DOWN);
                BigDecimal forecastQuantity = new BigDecimal(forecastOrderLineSDO.getQuantity()).setScale(3, RoundingMode.DOWN);
                if (forecastQuantity.compareTo(existInventory) > 0) {
                    throw new FunctionException("OTS-06-005-00-15-024", forecastOrderLineSDO.getGoodsCode(), existInventory.intValue());
                }
            }
        }
    }

    @NotNull
    private Integer addForecastOrderLine(Integer num, ForecastOrderLineSDO forecastOrderLineSDO) {

        //创建子单
        //判断是否存在同一货品
//        ForecastOrderLineSDO tmp = new ForecastOrderLineSDO();
//        tmp.setScItemId(forecastOrderLineSDO.getScItemId());
//        tmp.setMainOrderId(forecastOrderSDO.getId());
//        List<ForecastOrderLineSDO> sdoList = forecastOrderLineQueryRepository.queyrLineDetailList(tmp);
//        if (CollectionUtils.isNotEmpty(sdoList)) {
//            throw new FunctionException("OTS-04-001-00-15-014");
//        }
        ForecastOrderSDO forecastOrderSDO = forecastOrderLineQueryRepository.queryByOrderId(this.forecastOrderSDO);
        List<Integer> integers = new ArrayList<>();
        List<ForecastOrderLineSDO> forecastOrderLineSDOList1 = forecastOrderSDO.getForecastOrderLineSDOList();
        if (CollectionUtils.isNotEmpty(forecastOrderLineSDOList1)) {
            for (ForecastOrderLineSDO forecastOrderLineSDO1 : forecastOrderLineSDOList1) {
                if (StringUtils.isNotEmpty(forecastOrderLineSDO1.getSerialNumber())) {
                    integers.add(Integer.valueOf(forecastOrderLineSDO1.getSerialNumber()));
                }
            }
        }
        if (CollectionUtils.isNotEmpty(integers)) {
            Integer integer = integers.stream().reduce(Integer::max).get();
            num = integer / 10;
        }
        //设置行号
        num++;
        Integer serialNumber = num * 10;
        forecastOrderLineSDO.setSerialNumber(serialNumber.toString());
        //设置位草稿状态
        if (Objects.nonNull(this.forecastOrderSDO.getWareHouseCode())) {
            forecastOrderLineSDO.setWarehouseArea(this.forecastOrderSDO.getWareHouseCode());
        }
        forecastOrderLineSDO.setCustomerCode(this.forecastOrderSDO.getCustomerCode());
        forecastOrderLineSDO.setStatus(forecastOrderSDO.getStatus());
        forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.WAITING_DEAL.getStatus());
        forecastOrderLineSDO.setMainOrderId(this.forecastOrderSDO.getId());
        forecastOrderLineSDO.setMainOrderBizId(forecastOrderSDO.getOrderBizId());
        forecastOrderLineSDO.setModifierName(forecastOrderSDO.getModifierName());
        forecastOrderLineSDO.setCreatorId(forecastOrderSDO.getModifierId());
        forecastOrderLineSDO.setCreatorName(forecastOrderSDO.getModifierName());
        //默认累计回复数量为0
        forecastOrderLineSDO.setActualTotalReplyAmount(0);

        //设置总金额
        if (StringUtils.isNotEmpty(forecastOrderLineSDO.getQuantity()) && Objects.nonNull(forecastOrderLineSDO.getUnitPrice())) {
            forecastOrderLineSDO.setTotalFee(Long.parseLong(forecastOrderLineSDO.getQuantity()) * forecastOrderLineSDO.getUnitPrice());
        }
        if (CollectionUtils.isNotEmpty(forecastOrderLineSDO.getSaleUnitList())) {
            HashMap<String, Object> stringObjectHashMap = MapUtils.isEmpty(forecastOrderLineSDO.getFeatures()) ? new HashMap<>() : (HashMap<String, Object>) forecastOrderLineSDO.getFeatures();
            stringObjectHashMap.put(ForecastConstants.SALE_UNIT_LIST, forecastOrderLineSDO.getSaleUnitList());
            forecastOrderLineSDO.setFeatures(stringObjectHashMap);
        }
        forecastOrderLineWriteRepository.save(forecastOrderLineSDO);
        return num;
    }

    private void modifyForecastOrderLine(ForecastOrderLineSDO forecastOrderLineSDO, Integer qty) {
        forecastOrderLineSDO.setModifierId(forecastOrderSDO.getModifierId());
        forecastOrderLineSDO.setModifierName(forecastOrderSDO.getModifierName());
        //设置总金额
        if (StringUtils.isNotEmpty(forecastOrderLineSDO.getQuantity()) && Objects.nonNull(forecastOrderLineSDO.getUnitPrice())) {
            forecastOrderLineSDO.setTotalFee(Long.parseLong(forecastOrderLineSDO.getQuantity()) * forecastOrderLineSDO.getUnitPrice());
        }
        ForecastOrderLineSDO orderLineFeatures = getOrderLineFeatures(forecastOrderLineSDO, qty);


        forecastOrderLineWriteRepository.modify(orderLineFeatures);
    }

    /**
     * 预报订单提交   白兴雷
     *
     * @return
     */

    public Result<Boolean> submit(ApiContext apiContext) {
        //多线程下调用会丢失登录用户,从上下文中获取操作人赋值
        LoginUser loginUser = new LoginUser(apiContext.getEmployeeId(),apiContext.getEmployeeName(),apiContext.getEmployeeName());
        //校验仓库是否禁用
        QueryWarehouseByIdRequest byIdRequest = new QueryWarehouseByIdRequest();
        byIdRequest.setId(forecastOrderSDO.getWareHouseCode());
        Result<WarehouseInfo> warehouseInfoResult = unifiedInventoryService.queryWarehouseById(byIdRequest);
        if (warehouseInfoResult == null || warehouseInfoResult.getResult() == null || warehouseInfoResult.getResult().getStatus() == null) {
            return Result.fail("888", "未查询对应的仓库");
        }
        if (warehouseInfoResult.getResult().getStatus() == 2) {
            return Result.fail("999", "此仓库禁用,不允许提交");
        }
        if (CollectionUtils.isEmpty(forecastOrderSDO.getForecastOrderLineSDOList())) {
            throw new FunctionException("OTS-04-001-00-15-001");
        }
        boolean isSucees = true;
        //判断当前状态是否可以提交
        //根据查询结果 判断是时间段还是截止时间 是拦截还是提示
        //如果是拦截的话不允许提交  提示的话可以提交
        MoreConditionQueryRequest moreConditionQueryRequest = new MoreConditionQueryRequest();
        moreConditionQueryRequest.setStrategyType(StrategyTypeEnum.VALIDITY.getCode());
        moreConditionQueryRequest.setOrganizationCode(forecastOrderSDO.getOrganizationCode());//forecastOrderSDO.getOrganizationCode()
        moreConditionQueryRequest.setChannelCode(forecastOrderSDO.getChannelCode());//forecastOrderSDO.getChannelCode()
        moreConditionQueryRequest.setWareHouseCode(forecastOrderSDO.getWareHouseCode());
        log.info("ForecastOrderEntity|submit|" + forecastOrderSDO.getOrderBizId() + "|查询有效期校验|request|", JSONObject.toJSONString(moreConditionQueryRequest));
        Result<MoreConditionQueryResponse> moreConditionQueryResponseResult = strategyQueryService.moreConditionQuery(moreConditionQueryRequest);
        log.info("ForecastOrderEntity|submit|" + forecastOrderSDO.getOrderBizId() + "|查询有效期校验|result|", JSONObject.toJSONString(moreConditionQueryResponseResult));
        MoreConditionQueryResponse moreConditionQueryResponse = moreConditionQueryResponseResult.getResult();
        boolean isFlag = false;
        if (Objects.nonNull(moreConditionQueryResponse)) {
            StrategySDO strategySDO = moreConditionQueryResponse.getStrategySDO();
            List<DimensionSDO> dimensionSDOList = strategySDO.getDimensionSDOList();
            DimensionSDO dimensionSDO = dimensionSDOList.get(0);
            //获取规则
            String value = dimensionSDO.getRuleName();
            if (StringUtils.equals(RuleTypeEnum.TIME_POINT.getCode(), value)) {
                //获取规则值
                String ruleValue = dimensionSDO.getRuleValue();
                //判断截止时间是否满足 当前时间大于截止时间 不满足
                boolean compare = CalendarCompareUtil.compareDateTimes(null, ruleValue);
                if (compare) {
                    Boolean executeAction = dimensionSDO.getExecuteAction();
                    if (executeAction) {
//                        throw new FacadeException("OTS-04-001-00-15-018");
                        return Result.fail("OTS-04-001-00-15-018", "预报订单有效性检查失败，不允许提交订单已保存到草稿");
                    } else {
                        isFlag = true;
                    }
                }
            }
            if (StringUtils.equals(RuleTypeEnum.TIME_FRAME.getCode(), value)) {
                String ruleValue = dimensionSDO.getRuleValue();
                String substring = ruleValue.substring(ruleValue.indexOf("[") + 1, ruleValue.indexOf("]")).replace("\"", "");
                String[] split = substring.split(",");

                String ruleValueSplit = split[0];
                String ruleValueSplit1 = split[1];
                boolean compareDateTimes = CalendarCompareUtil.compareDateTimes(ruleValueSplit, ruleValueSplit1);
                //如果为true满足可以提交
                if (!compareDateTimes) {
                    Boolean executeAction = dimensionSDO.getExecuteAction();
                    if (executeAction) {
                        return Result.fail("OTS-04-001-00-15-018", "预报订单有效性检查失败，不允许提交订单已保存到草稿");
                    } else {
                        isFlag = true;
                    }
                }
            }
        }
        forecastOrderSDO.setStatus(ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue());
        forecastOrderSDO.setModifierId(apiContext.getEmployeeId());
        forecastOrderSDO.setModifierName(apiContext.getEmployeeName());

        // 提交子单
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderSDO.getForecastOrderLineSDOList()) {
            //add by myw,补货订单没有选中活动ID和活动项目号不允许提交,20221128
            if (ForecastOrderTag.RESTOCK_FORECAST.getValue().equals(forecastOrderSDO.getOrderType())){
                if (StringUtils.isBlank(forecastOrderLineSDO.getActivityCode())||StringUtils.isBlank(forecastOrderLineSDO.getActivityNumber())){
                    throw new FunctionException("OTS-04-001-00-15-057");
                }
            }

            // add by myw,校验子单价格 0303需求 预报单价格校验后移至预报单提交
            ForecastOrderLineSDO query = forecastOrderLineQueryRepository.query(String.valueOf(forecastOrderLineSDO.getId()));

            if (query.getUnitPrice() == null || query.getUnitPrice() < 0L) {
                throw new FunctionException("OTS-04-001-00-15-022");
            }

            if (StringUtils.isEmpty(forecastOrderLineSDO.getQuantity())) {
                throw new FunctionException("OTS-04-001-00-15-002");
            }
            //生效时，进行每日库存判断
            // 校验每日库存限量 在提交的时候校验每日库存
//            if (ForecastStatusEnum.DRAFT.getNumValue().equals(forecastOrderSDO.getStatus())){
            verifyDailyInv(forecastOrderLineSDO);
//            }
            if (!isFlag) {
                queryAndDeduct(forecastOrderLineSDO);
            }
            forecastOrderLineSDO.setStatus(ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue());
            forecastOrderLineSDO.setModifierId(apiContext.getEmployeeId());
            forecastOrderLineSDO.setModifierName(apiContext.getEmployeeName());

            forecastOrderLineWriteRepository.submit(forecastOrderLineSDO);

        }
        if (isFlag) {
            Date vaildBeginTime = this.forecastOrderSDO.getVaildBeginTime();
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(vaildBeginTime);
            //把日期往后增加一天.整数往后推,负数往前移动
            calendar.add(Calendar.DATE, 1);
//                这个时间就是日期往后推一天的结果
            vaildBeginTime = calendar.getTime();
            forecastOrderSDO.setVaildBeginTime(vaildBeginTime);
//            // 设置为未生效 原因和上边注释原因一样
//            forecastOrderSDO.setStatus(ForecastStatusEnum.NOTACTIVE.getNumValue());
        }
        //提交主单
        isSucees = forecastOrderWriteRepository.submit(this.forecastOrderSDO);
        LogUtils.printOperateLog(this.forecastOrderSDO, ForecastOrderLogEnum.SUBMIT.getForecastOrderLogValue(), "提交预报订单", loginUser);
        //标识效期校验未通过 但是是提示
        if (isFlag) {
            return Result.success(true, "预报订单有效性检查失败，允许提交待调度次日回复");
        }
        return Result.success(isSucees, "预报订单有效性检查通过，耐心等待调度员当日回复");
    }

    private void queryAndDeduct(ForecastOrderLineSDO forecastOrderLineSDO) {
        String isInventory = "A";
        Integer dailyInventory = null;
        String allotLineId = null;
        try {
            QueryAllotAndDeductRequest queryAllotRequest = new QueryAllotAndDeductRequest();
            queryAllotRequest.setOrganizationCode(forecastOrderSDO.getOrganizationCode());
            queryAllotRequest.setChannelCode(forecastOrderSDO.getChannelCode());
            queryAllotRequest.setDepartmentCode(forecastOrderSDO.getDepartmentCode());
            queryAllotRequest.setSalesmanCode(forecastOrderSDO.getSalesmanCode());
            queryAllotRequest.setScItemId(forecastOrderLineSDO.getScItemId());
            Double doubleDuct = Integer.parseInt(forecastOrderLineSDO.getQuantity()) / Double.parseDouble(forecastOrderLineSDO.getUnitConvert() == null ? "1" : forecastOrderLineSDO.getUnitConvert());
            String duct = String.valueOf(new BigDecimal(doubleDuct).setScale(3, RoundingMode.DOWN));
            queryAllotRequest.setDeductQuantity(duct);
            queryAllotRequest.setWarehouseCode(forecastOrderSDO.getWareHouseCode());
            log.info("ForecastOrderEntity|submit|" + forecastOrderSDO.getOrderBizId() + "|获取每日库存请求|request|" + JSON.toJSONString(queryAllotRequest));
            Result<DailyInventoryDeductResponse> result = inventoryAllotLineWriteService.queryAndDeduct(queryAllotRequest);
            log.info("ForecastOrderEntity|submit|" + forecastOrderSDO.getOrderBizId() + "|获取每日库存响应|result|" + JSON.toJSONString(result));
            if (result != null && result.getResult() != null) {
                allotLineId = result.getResult().getAllotLineId();
                dailyInventory = new BigDecimal(result.getResult().getRealDeductQuantity()).multiply(new BigDecimal(forecastOrderLineSDO.getUnitConvert())).intValue();
            }
        } catch (FacadeException ex) {
            throw new FunctionException(ex);
        } catch (Exception e) {
            log.error("ForecastOrderEntity|submit|" + forecastOrderSDO.getOrderBizId() + "|获取每日库存异常|exception|", e);

        }

        Map<String, Object> features = forecastOrderLineSDO.getFeatures();
        if (MapUtils.isEmpty(forecastOrderLineSDO.getFeatures())) {
            features = new HashMap<>();
        }
        if (Objects.nonNull(dailyInventory)) {
            if (dailyInventory >= Integer.parseInt(forecastOrderLineSDO.getQuantity())) {
                isInventory = "C";
            } else if (dailyInventory >= 0 && (dailyInventory < Integer.parseInt(forecastOrderLineSDO.getQuantity()))) {
                isInventory = "B";
            }
        }
//                if (dailyInventory >= Integer.parseInt(forecastOrderLineSDO.getQuantity())) {
//                    isInventory = "C";
//                } else if (dailyInventory > 0 && (dailyInventory < Integer.parseInt(forecastOrderLineSDO.getQuantity()))) {
//                    isInventory = "B";
//                } else {
//                    isInventory = "A";
//                }
        switch (isInventory) {
//                    case "A":
//                        //每日库存为空  表示未分解
////                        features.put(ForecastConstants.DISINTEGRATION, DisintegrationInventorySEO.DISINTEGRATION_NOT.getNumValue());
//                        features.put(ForecastConstants.DISINTEGRATION_QTY, 0);
//                        break;
            case "B":
                //分解未满足
//                        features.put(ForecastConstants.DISINTEGRATION, DisintegrationInventorySEO.DISINTEGRATION_INVENTORY_NOT.getNumValue());
                features.put(ForecastConstants.DISINTEGRATION_QTY, dailyInventory);
                features.put(ForecastConstants.DISINTEGRATION_ALLOT_LINE_ID, allotLineId);
                break;
            case "C":
                //分解满足
//                        features.put(ForecastConstants.DISINTEGRATION, DisintegrationInventorySEO.DISINTEGRATION_INVENTORY_YES.getNumValue());
                features.put(ForecastConstants.DISINTEGRATION_QTY, Integer.parseInt(forecastOrderLineSDO.getQuantity()));
                features.put(ForecastConstants.DISINTEGRATION_ALLOT_LINE_ID, allotLineId);
                break;
        }
        forecastOrderLineSDO.setFeatures(features);
    }

    public boolean modifyDetailForecast() {
        LoginUser loginUser = epochLoginUserService.getLoginUser();
        //主订单的修改
        forecastOrderWriteRepository.modifyForecast(this.forecastOrderSDO);
        LogUtils.printOperateLog(this.forecastOrderSDO, ForecastOrderLogEnum.EDIT.getForecastOrderLogValue(), "编辑预报订单", loginUser);
        //保存新的子订单
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = forecastOrderSDO.getForecastOrderLineSDOList();
        if (CollectionUtils.isNotEmpty(forecastOrderLineSDOList)) {
            for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                if (null == forecastOrderLineSDO.getId()) {
                    forecastOrderLineSDO.setStatus(ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue());
                    forecastOrderLineSDO.setMainOrderId(forecastOrderSDO.getId());
                    forecastOrderLineWriteRepository.save(forecastOrderLineSDO);
                }
            }
        }
        return true;
    }

    /*
    更改销售预报单 王成
     */
    public Integer modify() {
        Integer count = 0;
        // 保存预报主单
//        boolean mainFlag= forecastOrderWriteRepository.modify(this.forecastOrderSDO);
//        flag = flag && mainFlag;
        // 保存预报子单
        // 行号
        Integer num = 0;
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderSDO.getForecastOrderLineSDOList()) {
            forecastOrderLineSDO.setMainOrderId(this.forecastOrderSDO.getId());
            //判断是不是新增的子单 老的子单更新 新的子单创建
//            ForecastOrderLineSDO oldForecastOrderLineSDO = forecastOrderLineQueryRepository.query(forecastOrderLineSDO); //现在通过判断是否传递id来判断   因为根据id查询 如果查询不到会直接报错
            if (StringUtils.isNotBlank(forecastOrderLineSDO.getMainOrderId())) {
                num++;
                forecastOrderLineSDO.setSerialNumber(num.toString());
                Integer modifyCount = forecastOrderLineWriteRepository.modify(forecastOrderLineSDO);
                count += modifyCount;
            } else {
                num++;
                forecastOrderLineSDO.setSerialNumber(num.toString());
                forecastOrderLineSDO.setStatus(ForecastStatusEnum.DRAFT.getNumValue());
                forecastOrderLineSDO.setStatus(ForecastDealStatusSEO.WAITING_DEAL.getStatus());
                forecastOrderLineSDO.setActualTotalReplyAmount(0);
                forecastOrderLineWriteRepository.save(forecastOrderLineSDO);
                count++;
            }
        }
        return count;
    }

    /**
     * 修改预报订单
     */

    public boolean updateReplyQuantity(Integer predictReplyAmount) {
        //修改成功
        boolean isSuccess = true;
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = forecastOrderSDO.getForecastOrderLineSDOList();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            forecastOrderLineSDO.setPredictReplyAmount(predictReplyAmount);
            isSuccess = forecastOrderLineWriteRepository.updateReplyQuantity(forecastOrderLineSDO);
        }
        return isSuccess;
    }

    public boolean updateForecastOrderLine() {
        //修改成功
        boolean isSuccess = true;
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = forecastOrderSDO.getForecastOrderLineSDOList();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            isSuccess = forecastOrderLineWriteRepository.updateForAnalysis(forecastOrderLineSDO);
        }
        return isSuccess;
    }

    /**
     * 确认预报订单 修改预报的处理状态
     */
    public boolean confirmUpdateDealForecast(ApiContext apiContext) {
//        LoginUser loginUser = epochLoginUserService.getLoginUser();
        //修改订单处理状态为
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        boolean isSuccess = true;
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
//            forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.CONFIRM_ING.getStatus());
//            forecastOrderLineSDO.setModifierId(apiContext.getEmployeeId());
//            forecastOrderLineSDO.setModifierName(apiContext.getEmployeeName());
//            Map<String, Object> features = forecastOrderLineSDO.getFeatures() == null ? new HashMap<>() : forecastOrderLineSDO.getFeatures();
            if (ObjectUtils.isEmpty(forecastOrderLineSDO.getPredictReplyAmount())) {
                throw new FunctionException("OTS-04-001-00-15-032", "预计回复数量不能为0！");
            }
            if (forecastOrderLineSDO.getPredictReplyAmount() == 0) {
                throw new FunctionException("OTS-04-001-00-15-032", "预计回复数量不能为0！");
            }
//            isSuccess = forecastOrderLineWriteRepository.submit(forecastOrderLineSDO);
        }
        //将数据的信息插入确认队列的表中
        List<DealLineSDO> collect = Nullable.stream(forecastOrderLineSDOList).map(forecastOrderLineSDO -> {
            DealLineSDO dealLineSDO = new DealLineSDO();
            dealLineSDO.setForecastOrderLineId(forecastOrderLineSDO.getId().toString());
            dealLineSDO.setDealStatus(ForecastDealStatusSEO.CONFIRM_ING.getStatus());
            dealLineSDO.setDealType(ForecastDealTypeSEO.BATCH_CONFIRM.getDealTypeCode().toString());
            dealLineSDO.setModifierName(forecastOrderLineSDO.getModifierName());
            dealLineSDO.setModifierId(forecastOrderLineSDO.getModifierId());
            dealLineSDO.setDealTime(new Date());
            Date now = new Date();
            SimpleDateFormat f = new SimpleDateFormat("yyyyMMddhhmmss");
            String format = f.format(now);//20211015030520
            dealLineSDO.setBatchNumber(format);
            return dealLineSDO;
        }).collect(Collectors.toList());
        boolean b = dealLineWriteRepository.batchCreate(collect);
//        LogUtils.printOperateLog(this.forecastOrderSDO, ForecastOrderLogEnum.BATCH_CONFIRM.getForecastOrderLogValue(), "确认预报订单", loginUser);

        return isSuccess;
    }


    /**
     * 确认预报订单 修改预报的处理状态
     */
    public boolean activityUpdateDealForecast(ApiContext apiContext) {
        //TODO 性能优化点： 这里可以直接从内存中获取单据数据，而非重新捞取
        //修改订单处理状态为
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        //为了内存值传递
        Map<Long, List<ForecastOrderLineSDO>> inputOrderLineMap = Nullable.stream(forecastOrderLineSDOList).collect(Collectors.groupingBy(ForecastOrderLineSDO::getId));
        boolean isSucess = true;
        log.info("查下活动前，预报主单ID={}", this.forecastOrderSDO.getId());
        //补货订单不走活动检查逻辑
        if (!ForecastOrderTag.RESTOCK_FORECAST.getValue().equals(forecastOrderSDO.getOrderType())) {
            List<ActivitySDO> activitySDOSList = queryActivity(forecastOrderLineSDOList);
            Set<String> haveActivitySubOrderIdSet = new HashSet<>();
            if (CollectionUtils.isNotEmpty(activitySDOSList)) {
                Map<String, List<ActivitySDO>> activitySDOMap = activitySDOSList.stream().collect(Collectors.groupingBy(ActivitySDO::getSubOrderId));
                if (MapUtils.isNotEmpty(activitySDOMap)) {
                    for (String subId : activitySDOMap.keySet()) {
                        ForecastOrderLineSDO forecastOrderLineSDO = forecastOrderLineQueryRepository.query(subId);
                        List<ActivitySDO> activitySDOS = activitySDOMap.get(subId);
                        //根据活动命中的情况对预报子单进行更新
                        updateActivityInformation(forecastOrderLineSDO, activitySDOS, apiContext);
                        if (inputOrderLineMap.containsKey(forecastOrderLineSDO.getId())) {
                            ForecastOrderLineSDO inputObject = inputOrderLineMap.get(forecastOrderLineSDO.getId()).get(0);
                            BeanUtils.copyProperties(forecastOrderLineSDO, inputObject);

                        }
                    }
                    haveActivitySubOrderIdSet.addAll(activitySDOMap.keySet());
                }
            }

            forecastOrderLineSDOList.forEach(orderLineSDO -> {
                if (!haveActivitySubOrderIdSet.contains(orderLineSDO.getId().toString())) {
                    DeleteActivityForecastRequest deleteActivityForecastRequest = new DeleteActivityForecastRequest();
                    deleteActivityForecastRequest.setId(String.valueOf(orderLineSDO.getId()));
                    forecastOrderWriteService.deleteActivityForecast(deleteActivityForecastRequest);
                    //内存拷贝 值传递
                    if (inputOrderLineMap.containsKey(orderLineSDO.getId())) {
                        ForecastOrderLineSDO inputObject = inputOrderLineMap.get(orderLineSDO.getId()).get(0);
                        BeanUtils.copyProperties(orderLineSDO, inputObject);
                        //修改活动id
                        inputObject.setActivityCode("");
                        //修改活动名称
                        inputObject.setActivityName("");
                        //修改活动金额,这个不做设置
                        inputObject.setActivityPrice(0L);
                        //修改活动赠品情况
                        Map<String, Object> features = inputObject.getFeatures();
                        //删除赠品信息
                        features.remove(ForecastConstants.GIFTLIST);
                        //删除活动标识
                        features.remove(ForecastConstants.ACTIVITY_TAG);
                        //删除活动详情
                        features.remove(ForecastConstants.ACTIVITY_DETAILS);
                    }
                }
            });

        }
        //查询命中活动详情

        return isSucess;
    }


    private boolean updateActivityInformation(ForecastOrderLineSDO forecastOrderLineSDO, List<ActivitySDO> activitySDOS, ApiContext apiContext) {
        Map<String, Object> features = forecastOrderLineSDO.getFeatures();
        if (CollectionUtils.isEmpty(activitySDOS) && MapUtils.isNotEmpty(features)) {
            log.info("活动未命中::" + forecastOrderLineSDO.getIdemId());
            if (Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))) {
                features.remove(ForecastConstants.ACTIVITY_DETAILS);
            }
            return true;
        }

        //修改状态为检查中
//            forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.CHECk_ING.getStatus());
        if (apiContext != null) {
            forecastOrderLineSDO.setModifierId(apiContext.getEmployeeId());
            forecastOrderLineSDO.setModifierName(apiContext.getEmployeeName());
        }
        //调用活动检查接口 获取返回值判断命中活动情况 list<object>
        /**
         *  ZS01-买赠
         *              * ZS02-搭赠
         *              * ZS03-特价
         *              * ZS42-补货
         */
        if (CollectionUtils.isNotEmpty(activitySDOS)) {
            //设置查询活动参数
            features.remove(ForecastConstants.ACTIVITY_DETAILS);
            features.put(ForecastConstants.ACTIVITY_MESSAGE, "活动检查成功！");
            activitySDOS.forEach(i -> {
                i.setIsSelect(false);
            });

            //按活动号进行排序，当前是升序排列
            Collections.sort(activitySDOS, Comparator.comparing(ActivitySDO::getActivityCode));
            //按组管控的活动 需要使用ext表中的活动剩余金额和活动量
            for (ActivitySDO activitySDO : activitySDOS) {
                if (StringUtils.isNotBlank(activitySDO.getGroupControl()) && "X".equals(activitySDO.getGroupControl())) {
                    String activityCode = activitySDO.getActivityCode();

                    QueryActivityTitleByActivityIdRequest queryActivityTitleByActivityIdRequest = new QueryActivityTitleByActivityIdRequest();
                    queryActivityTitleByActivityIdRequest.setActivityId(activityCode);
                    ActivityTitleLoadListVO titleResp = activityTitleService.queryActivityTitleByActivityId(queryActivityTitleByActivityIdRequest);
                    if (Objects.nonNull(titleResp)) {
                        String activityNoteId = titleResp.getActivityNoteId();
                        ActivityTitleExtCreateRequest activityTitleExtCreateRequest = new ActivityTitleExtCreateRequest();
                        activityTitleExtCreateRequest.setActivityNoteId(activityNoteId);
                        ActivityTitleExt activityTitleExt = activityTitleExtService.queryActivityTitleExt(activityTitleExtCreateRequest);
                        if (Objects.nonNull(activityTitleExt)) {
                            long activityRemainQuantity = Nullable.of(activityTitleExt.getApplyItemQuantity()).orElse(0L) - Nullable.of(activityTitleExt.getActivityOccupyQuantity()).orElse(0L);
                            long activityRemainFee = Nullable.of(activityTitleExt.getApplyFee()).orElse(0L) - Nullable.of(activityTitleExt.getActivityOccupyFee()).orElse(0L);
                            activitySDO.setActivitydeal((int) activityRemainQuantity);
                            activitySDO.setActivityfee(activityRemainFee);
                        }

                    }
                }
            }

            features.put(ForecastConstants.ACTIVITY_DETAILS, activitySDOS);
            if (activitySDOS.size() > 1) {
                //大于一的时候命中多个活动 表示后续需要修改
                features.put(ForecastConstants.ACTIVITY_TAG, 1);
                //对多个活动要进行设置选中逻辑。
                // 同种活动类型设置第一个选中，不同种活动类型设置，对第一个活动类型设置为选中，其他的均为不选中
                Map<String, List<ActivitySDO>> map = activitySDOS.stream().collect(Collectors.groupingBy(ActivitySDO::getActivityType));
                for (Map.Entry<String, List<ActivitySDO>> entry : map.entrySet()) {
                    List<ActivitySDO> value = entry.getValue();
                    for (int i = 0; i < value.size(); i++) {
                        if (i == 0) {
                            value.get(0).setIsSelect(true);
                        } else {
                            value.get(i).setIsSelect(false);
                        }
                    }
                }

            } else if (1 == activitySDOS.size()) {
                // 并且只有一个商品 将活动信息存放到features中
                if ("ZS42".equals(activitySDOS.get(0).getActivityType()) && activitySDOS.size() == 1) {
                    features.put(ForecastConstants.ACTIVITY_TAG, 0);
                    activitySDOS.get(0).setIsSelect(true);
                    features.put(ForecastConstants.ACTIVITY_NUMBER, activitySDOS.get(0).getActivityTermid());
                    features.put(ForecastConstants.ACTIVITY_DETAILS, activitySDOS);
                }
                // 赠品活动
                if ("ZS02".equals(activitySDOS.get(0).getActivityType()) && activitySDOS.size() == 1) {
                    if (activitySDOS.get(0).getGiftList().size() > 1) {
                        features.put(ForecastConstants.ACTIVITY_TAG, 1);
                    } else {
                        features.put(ForecastConstants.ACTIVITY_TAG, 0);
                        features.put(ForecastConstants.ACTIVITY_NUMBER, activitySDOS.get(0).getActivityTermid());
                        activitySDOS.get(0).setIsSelect(true);
                        features.put(ForecastConstants.ACTIVITY_DETAILS, activitySDOS);
                    }
                }
                if ("ZS03".equals(activitySDOS.get(0).getActivityType()) && activitySDOS.size() == 1) {
                    Long activityFee = activitySDOS.get(0).getActivityfee();


                    Long specialOfferPrice = null != activitySDOS.get(0).getSpecialOfferPrice() ? activitySDOS.get(0).getSpecialOfferPrice() : 0L;
                    Long unitPrice = forecastOrderLineSDO.getUnitPrice();

                    //按活动剩余数量的可提报量
                    long quantityCanQuantity = activitySDOS.get(0).getActivitydeal();
                    //按费用计算可提报量
                    long feeCanQuantity = (!Objects.equals(unitPrice, specialOfferPrice)) ? activityFee / (unitPrice - specialOfferPrice) : quantityCanQuantity;

                    //取 按费用计算可提报量 和 活动剩余数量的最小值
                    long maxCanQuantity = Math.min(feeCanQuantity, quantityCanQuantity);


                    if (maxCanQuantity < forecastOrderLineSDO.getPredictReplyAmount()) {
                        features.put(ForecastConstants.ACTIVITY_TAG, 1);
                    } else {
                        features.put(ForecastConstants.ACTIVITY_TAG, 0);
                        features.put(ForecastConstants.ACTIVITY_NUMBER, activitySDOS.get(0).getActivityTermid());
                        activitySDOS.get(0).setIsSelect(true);
                        features.put(ForecastConstants.ACTIVITY_DETAILS, activitySDOS);
                        //只有特价活动有特价 活动特价
                        forecastOrderLineSDO.setActivityPrice(specialOfferPrice);
                        //设置活动总金额
                        if (null != activitySDOS.get(0).getSpecialOfferPrice()
                                && StringUtils.isNotEmpty(forecastOrderLineSDO.getQuantity())) {
                            forecastOrderLineSDO.setTotalActivityFee(specialOfferPrice
                                    * Long.parseLong(forecastOrderLineSDO.getQuantity()));
                        }
                    }
                }
            }
            //标识命中活动
            features.put(ForecastConstants.ISSELECT_ACTIVITY, 1);
            features.put(ForecastConstants.ACTIVITY_TYPE, activitySDOS.get(0).getActivityType());
            forecastOrderLineSDO.setFeatures(features);
            forecastOrderLineSDO.setActivityName(activitySDOS.get(0).getActivityName());
            //活动id
            forecastOrderLineSDO.setActivityCode(activitySDOS.get(0).getActivityCode());
            //设置活动号
            forecastOrderLineSDO.setActivityNumber(activitySDOS.get(0).getActivityTermid());
        } else {
            //标识未命中活动
            features.put(ForecastConstants.ISSELECT_ACTIVITY, 0);
            features.put(ForecastConstants.ACTIVITY_MESSAGE, "该单据未命中活动！");
        }
        return forecastOrderLineWriteRepository.update(forecastOrderLineSDO);
    }

    private List<ActivitySDO> queryActivity(List<ForecastOrderLineSDO> forecastOrderLineSDOs) {
        QueryActivityRequest request = new QueryActivityRequest();
        List<ActivityInfoRequest> activityInfoRequestList = new ArrayList<>();
        //构建活动信息请求列表
        buildActivityInfoRequestList(forecastOrderLineSDOs, activityInfoRequestList);
        request.setActivityInfoRequestList(activityInfoRequestList);
        Map<String, String> map = new HashMap<>();
        map.put(CODE_FLAG, INNER_CODE_TO_OUT_CODE);
        request.setFeatures(map);
        //获取出参
        List<ActivitySDO> activitySDOS = new ArrayList<>();
        try {
            List<ActivityInfoRequest> notZeroReq = Nullable.stream(request.getActivityInfoRequestList()).filter(o -> {
                List<ActivityItemInfoRequest> collect = Nullable.stream(o.getItemList()).filter(x -> 0L == x.getItemQuantity()).collect(Collectors.toList());
                return !CollectionUtils.isNotEmpty(collect);
            }).collect(Collectors.toList());
            request.setActivityInfoRequestList(notZeroReq);
            Result<ActivityResponse> activityResponseResult = activityQueryService.batchQueryCanUsingActivityExpand(request);
            ActivityResponse result = activityResponseResult.getResult();
            if (Objects.nonNull(result) && CollectionUtils.isNotEmpty(result.getActivityInfoResponseList())) {
                for (ActivityInfoResponse activityInfoResponse : result.getActivityInfoResponseList()) {
                    List<ActivityTermResponse> activityTermList = activityInfoResponse.getActivityTermList();
                    ActivitySDO activitySDO = new ActivitySDO();
                    activitySDO.setDisableChooseFlag(activityInfoResponse.getDisableChooseFlag());
                    activitySDO.setIsSelect(false);
                    //设置活动id
                    activitySDO.setActivityCode(activityInfoResponse.getActivityId());

                    //设置按组管控
                    activitySDO.setGroupControl(activityInfoResponse.getGroupControl());
                    //设置子单id
                    activitySDO.setSubOrderId(activityInfoResponse.getSubOrderId());
                    //设置活动名称
                    activitySDO.setActivityName(activityInfoResponse.getActivityNoteName());
                    //设置活动剩余量
                    ActivityTermResponse activityTermResponse = activityTermList.get(0);
                    activitySDO.setActivitydeal(activityTermResponse.getActivityRemainingQuantity());
                    //设置版本号
                    activitySDO.setVersion(activityTermResponse.getVersion());
                    /**
                     * ZS01-买赠
                     * ZS02-搭赠
                     * ZS03-特价
                     * ZS42-补货
                     */
                    activitySDO.setActivityType(activityInfoResponse.getActivityFacadeCode());
                    //设置活动力度说明
                    activitySDO.setIntensityOfActivityDesc(activityTermResponse.getIntensityOfActivityDesc());
                    //设置活动剩余金额
                    activitySDO.setActivityfee(activityTermResponse.getActivityRemainingFee());
                    //设置项目id
                    activitySDO.setActivityTermid(activityTermResponse.getActivityTermId());
                    //增品活动的活动类型
                    activitySDO.setGiftActivityType(activityTermResponse.getGiftActivityType());
                    //赠品活动是否固定展示赠品
                    activitySDO.setIsFixedGift(activityTermResponse.getIsFixedFlag());
                    //参与活动的子单集合
                    activitySDO.setJoinSubOrderIdList(activityTermResponse.getJoinFullBuySubIdList());
                    //设置特价
                    if (ActivityTypeEnum.SPECIAL_OFFER_PRICE.getValue().equals(activityInfoResponse.getActivityFacadeCode())) {
                        BigDecimal specialPrice = new BigDecimal(activityTermResponse.getSpecialOfferPrice());
                        //特价要从元转换成分
                        activitySDO.setSpecialOfferPrice(specialPrice.longValue());
                        //设置公用组，只有特价有
                        activitySDO.setCommonGroupFlag(activityTermResponse.getCommonGroupFlag());
                    }
                    List<GiftSDO> chooseGiftList = new ArrayList<>();
                    if (ActivityTypeEnum.TAKE_GIFT.getValue().equals(activityInfoResponse.getActivityFacadeCode())) {
                        List<ActivityItemInfo> giftList1 = activityTermResponse.getGiftList();
                        if (CollectionUtils.isNotEmpty(giftList1)) {
                            for (ActivityItemInfo activityItemInfo : giftList1) {
                                GiftSDO giftSDO = new GiftSDO();
                                giftSDO.setGiftName(activityItemInfo.getItemName());
                                giftSDO.setGiftNumber(activityItemInfo.getItemQuantity());
                                giftSDO.setScItemId(activityItemInfo.getItemId());
                                giftSDO.setGiftSalesUnitCode(activityItemInfo.getSalesUnit());
                                giftSDO.setGiftUnitCode(activityItemInfo.getStockUnit());
                                giftSDO.setConversionUnit(activityItemInfo.getConversionUnit());
                                giftSDO.setGiftDisable(activityItemInfo.getDisableChooseFlag());
                                giftSDO.setSegOrderNo(activityItemInfo.getSegOrderNo());
                                //赠品单位转换关系查询
                                QuerySaleUnitRequest querySaleUnitRequest = new QuerySaleUnitRequest();
                                querySaleUnitRequest.setScItemId(activityItemInfo.getItemId());
                                querySaleUnitRequest.setInventoryUnit("件");
                                querySaleUnitRequest.setInventoryUnitCode("PC");
                                Result<List<SelectCombox>> saleUnitList = forecastOrderLineQueryService.querySaleUnitList(querySaleUnitRequest);
                                if (Objects.nonNull(saleUnitList) && CollectionUtils.isNotEmpty(saleUnitList.getResult())) {
                                    String ext = saleUnitList.getResult().stream().filter(o -> o.getValue().equals(activityItemInfo.getSalesUnit())).findFirst().orElse(new SelectCombox(
                                    )).getExt();
                                    String unitCover = StringUtils.isNotBlank(ext) ? ext : "1";
                                    giftSDO.setConversionUnit(unitCover);
                                }
                                try {
                                    ScItemUnitLoadListRequest scItemUnitLoadListRequest = new ScItemUnitLoadListRequest();
                                    scItemUnitLoadListRequest.setCode(activityItemInfo.getSalesUnit());
                                    Result<List<ScItemUnit>> listResult = scItemUnitService.loadScItemUnitList(scItemUnitLoadListRequest);
                                    if (Objects.nonNull(listResult) && CollectionUtils.isNotEmpty(listResult.getResult())) {
                                        ScItemUnit scItemUnit = listResult.getResult().get(0);
                                        giftSDO.setGiftSalesUnit(scItemUnit.getName());
                                    }
                                    IdQueryRequest idQueryRequest = new IdQueryRequest();
                                    idQueryRequest.setId(giftSDO.getScItemId());
                                    Result<ScItemSDO> scItemById = scItemQueryService.getScItemById(idQueryRequest);
                                    ScItemSDO scItemSDO = scItemById.getResult();
                                    if (Objects.nonNull(scItemSDO)) {
                                        giftSDO.setScItemCode(scItemSDO.getOuterId());
                                    }
                                } catch (Exception e) {
                                    log.error("查询商品属性失败", e);
                                }
                                Long price = -1L;

                                price = priceQueryUtils.obtainGiftPrice(forecastOrderSDO, giftSDO);
                                if (price < 0) {
                                    log.error("查询赠品活动价格失败,赠品Id:" + activityItemInfo.getItemId() + "活动ID:" + activityInfoResponse.getActivityId());
                                    throw new FacadeException("OTS-04-001-00-15-033");
                                }
                                giftSDO.setGiftPrice(price);
                                chooseGiftList.add(giftSDO);
                            }
                        }
                        if (CollectionUtils.isNotEmpty(chooseGiftList)) {

                            //任选赠品默认选中第一条
                            List<GiftSDO> canChooseList = chooseGiftList.stream().filter(o -> !o.getGiftDisable()).collect(Collectors.toList());
                            //禁止选中的赠品（固定在赠品列表，不可编辑）
                            List<GiftSDO> cannotChooseList = chooseGiftList.stream().filter(GiftSDO::getGiftDisable).collect(Collectors.toList());

                            if (CollectionUtils.isNotEmpty(canChooseList)) {
                                Map<String, List<GiftSDO>> unitGiftMap = canChooseList.stream().collect(Collectors.groupingBy(GiftSDO::getGiftSalesUnitCode));

                                for (Map.Entry<String, List<GiftSDO>> entry : unitGiftMap.entrySet()) {
                                    GiftSDO giftSDO = entry.getValue().get(0);
                                    cannotChooseList.add(giftSDO);
                                }
                            }
                            //根据坎级序号排序
                            List<GiftSDO> sortedChooseList = Nullable.stream(cannotChooseList).sorted(Comparator.comparing(GiftSDO::getSegOrderNo, Comparator.reverseOrder())).collect(Collectors.toList());
                            activitySDO.setChooseGiftList(sortedChooseList);

                        }
                    }
                    //根据坎级序号排序
                    List<GiftSDO> sortedGiftList = Nullable.stream(chooseGiftList).sorted(Comparator.comparing(GiftSDO::getSegOrderNo, Comparator.reverseOrder())).collect(Collectors.toList());
                    activitySDO.setGiftList(sortedGiftList);
                    activitySDOS.add(activitySDO);
                }
            }
        } catch (Exception e) {
            log.error("查询活动异常处理:", e);
        }
        return activitySDOS;
    }

    /**
     * 补货活动查询信息参数构建
     */
    private ActivityInfoRequest createActivityInfoRequest(ForecastOrderLineSDO forecastOrderLineSDO) {
        ActivityInfoRequest infoRequest = new ActivityInfoRequest();
        infoRequest.setClientId(forecastOrderSDO.getCustomerCode());
        infoRequest.setMainOrderId(this.forecastOrderSDO.getId());
        infoRequest.setSubOrderId(String.valueOf(forecastOrderLineSDO.getId()));
        infoRequest.setActivityUseTime(new Date());
        infoRequest.setDeliveryDate(this.forecastOrderSDO.getCustomerExpectTDate());
        infoRequest.setSalesOrganization(forecastOrderSDO.getOrganizationCode());
        infoRequest.setBusinessChannel(forecastOrderSDO.getChannelCode());
        infoRequest.setShipAddressId(forecastOrderSDO.getReceiveAddressCode());
        infoRequest.setOrderType(forecastOrderSDO.getOrderType());
        List<ActivityItemInfoRequest> itemList = new ArrayList<>();
        ActivityItemInfoRequest itemInfoRequest = new ActivityItemInfoRequest();
        itemInfoRequest.setItemId(forecastOrderLineSDO.getScItemId());
        itemInfoRequest.setSalesUnit(forecastOrderLineSDO.getSaleUnitCode());
        itemInfoRequest.setItemQuantity(Long.parseLong(String.valueOf(forecastOrderLineSDO.getPredictReplyAmount())));
        itemList.add(itemInfoRequest);
        infoRequest.setItemList(itemList);
        return infoRequest;
    }

    /**
     * 构建活动信息请求列表
     *
     * @param forecastOrderLineSDOs
     * @param activityInfoRequestList
     */
    private void buildActivityInfoRequestList(List<ForecastOrderLineSDO> forecastOrderLineSDOs, List<ActivityInfoRequest> activityInfoRequestList) {
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOs) {

            ActivityInfoRequest infoRequest = new ActivityInfoRequest();
            List<ActivityItemInfoRequest> itemList = new ArrayList<>();
            ActivityItemInfoRequest itemInfoRequest = new ActivityItemInfoRequest();
            try {
                infoRequest.setClientId(forecastOrderSDO.getCustomerCode());
                infoRequest.setMainOrderId(this.forecastOrderSDO.getId());
                infoRequest.setSubOrderId(String.valueOf(forecastOrderLineSDO.getId()));
                infoRequest.setActivityUseTime(this.forecastOrderSDO.getCustomerExpectTDate());
                infoRequest.setDeliveryDate(this.forecastOrderSDO.getCustomerExpectTDate());
                infoRequest.setSalesOrganization(forecastOrderSDO.getOrganizationCode());
                infoRequest.setBusinessChannel(forecastOrderSDO.getChannelCode());
                infoRequest.setOrderType(forecastOrderSDO.getOrderType());
                infoRequest.setShipAddressId(forecastOrderSDO.getReceiveAddressCode());
                itemInfoRequest.setItemId(forecastOrderLineSDO.getScItemId());
                itemInfoRequest.setSalesUnit(forecastOrderLineSDO.getSaleUnitCode());
                itemInfoRequest.setItemQuantity(Long.parseLong(String.valueOf(forecastOrderLineSDO.getPredictReplyAmount())));
                itemList.add(itemInfoRequest);
                infoRequest.setItemList(itemList);

                Map<String, Object> features = forecastOrderLineSDO.getFeatures() == null ? new HashMap<>() : forecastOrderLineSDO.getFeatures();
                features.put(ForecastConstants.ACTIVITY_CHECK_PARAMS, infoRequest);
                forecastOrderLineWriteRepository.update(forecastOrderLineSDO);
            } catch (Exception e) {
                log.error("ERROR:Build activity info request failed", e);
            }

            activityInfoRequestList.add(infoRequest);
        }
    }

    /**
     * 确认预报订单 预报订单确认检查
     */
    @Deprecated
    public List<ConfirmForecastResponse> confirmCheckForecast(ConfirmForecastRequest confirmForecastRequest) {
        List<ConfirmForecastResponse> confirmForecastResponses = new ArrayList<>();
        ConfirmForecastResponse success = new ConfirmForecastResponse();
        //成功
        success.setTag("1");
        ConfirmForecastResponse failedForecastResponse = new ConfirmForecastResponse();
        //失败
        failedForecastResponse.setTag("2");
        ConfirmForecastResponse isCredit = new ConfirmForecastResponse();
        //信贷失败
        isCredit.setTag("3");
        List<String> successIds = new ArrayList<>();
        List<String> failedIds = new ArrayList<>();
        List<String> creditIds = new ArrayList<>();
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        //添加库存校验
        List<ConfirmForecastResponse> confirmForecastResponsesList = inventoryCheck(forecastOrderLineSDOList);
        if (CollectionUtils.isEmpty(confirmForecastResponsesList)) {
            for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                failedIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                //判断子订单是否需要经过活动检查
                backForecastUpdate(forecastOrderLineSDO, "库存不足不可以生成销售订单！");

            }
            return confirmForecastResponsesList;
        }
        Boolean[] isNeedCallParticipateActivity = new Boolean[1];
        isNeedCallParticipateActivity[0] = true;
        //start
        String sequenceNo = confirmForecastRequest.getSequenceNo();
        ParticipateInActivityResponse participateInActivityResponse1 = occupyActivity(forecastOrderLineSDOList, isNeedCallParticipateActivity, confirmForecastRequest);
        if (isNeedCallParticipateActivity[0]) {
            if (Objects.nonNull(participateInActivityResponse1)
                    && CollectionUtils.isNotEmpty(participateInActivityResponse1.getParticipateActivityResponseList())) {

                List<ParticipateActivityInfoResponse> participateActivityResponseList = participateInActivityResponse1.getParticipateActivityResponseList();
                Map<String, List<ParticipateActivityInfoResponse>> participateActivityInfoResponseMap = participateActivityResponseList.stream()
                        .collect(Collectors.groupingBy(e -> e.getSubOrderId()));

                for (String subId : participateActivityInfoResponseMap.keySet()) {
                    ForecastOrderLineSDO forecastOrderLineSDO1 = forecastOrderLineQueryRepository.query(subId);
                    Map<String, Object> features = forecastOrderLineSDO1.getFeatures() == null ? new HashMap<>() : forecastOrderLineSDO1.getFeatures();
                    List<ParticipateActivityInfoResponse> participateActivityInfoResponses = participateActivityInfoResponseMap.get(subId);
                    //活动返回值集合中有为false 的则为失败
                    List<ParticipateActivityInfoResponse> panduan = participateActivityInfoResponses.stream().filter(i ->
                            false == i.getParticipateResult()).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(panduan)) {
                        failedIds.add(subId);
                        //更新子单的失败信息
                        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                            //判断子订单是否需要经过活动检查
                            backForecastUpdate(forecastOrderLineSDO, "异常情况活动占用失败！");

                        }
                        List<ConfirmForecastResponse> confirmForecastResponseYuan = new ArrayList<>();
                        return confirmForecastResponseYuan;
                    }

                    //补全 feature 中的字段，原因一个字段对应多个不同类型的活动，需要添加不同的字段信息
                    for (ParticipateActivityInfoResponse participateActivityInfoResponse : participateActivityInfoResponses) {
                        if (participateActivityInfoResponse.getParticipateResult()) {
                            if (ActivityTypeEnum.SPECIAL_OFFER_PRICE.getValue().equals(participateActivityInfoResponse.getActivityType())) {
                                //特价活动添加占用活动成功的原品数量
                                features.put(ForecastConstants.ACTIVITY_INVENTORY, participateActivityInfoResponse.getParticipateSuccessItemCount());
                            }
//                        该字段会被覆盖，属于正常情况
                            features.put(ForecastConstants.CONFIRM_MESSAGE, participateActivityInfoResponse.getParticipateResultMsg());
                        }
                    }
                    //活动检查通过  获取活动量
                    forecastOrderLineSDO1.setFeatures(features);
                    forecastOrderLineWriteRepository.update(forecastOrderLineSDO1);

                    // todo bxl 袁登，为什么要这样做，不太懂
                    updateDealQueueStatus(forecastOrderLineSDO1);
                    successIds.add(subId);
                }
            } else {
                //异常情况活动占用失败！更新子单的失败信息
                for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                    failedIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                    //判断子订单是否需要经过活动检查
                    if (StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode())) {
                        backForecastUpdate(forecastOrderLineSDO, "异常情况活动占用失败！");
                    }
                }
            }
        }

        //库存校验成功的，没有活动的子单
        forecastOrderLineSDOList.stream().forEach(forecastOrderLineSDO -> {
            Map<String, Object> features = forecastOrderLineSDO.getFeatures();
            if (StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode()) && MapUtils.isNotEmpty(features) && Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))) {
                List<ActivitySDO> activitySDOList = JSONObject.parseArray(JSON.toJSONString(features.get(ForecastConstants.ACTIVITY_DETAILS)), ActivitySDO.class);
                List<ActivitySDO> activitySDOS = activitySDOList.stream().filter(activitySDO -> activitySDO.getIsSelect() == true).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(activitySDOS)) {
                    successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                }
            }

            if (StringUtils.isEmpty(forecastOrderLineSDO.getActivityCode())) {
                successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
            }
        });

        failedForecastResponse.setIds(failedIds);
        success.setIds(successIds);
        isCredit.setIds(creditIds);
        confirmForecastResponses.add(isCredit);
        confirmForecastResponses.add(success);
        confirmForecastResponses.add(failedForecastResponse);
        return confirmForecastResponses;
    }

    /**
     * 确认预报订单 预报订单确认检查
     */
    public ConfirmForecastResponse confirmCheckForecastNew(ConfirmForecastRequest confirmForecastRequest, Map<String, String> inventoryMap) {
        ConfirmForecastResponse confirmForecastResponse = new ConfirmForecastResponse();
        List<String> successIds = new ArrayList<>();
        List<String> failedIds = new ArrayList<>();
        Map<String, String> successIdsMap = new HashMap<>();
        Map<String, String> failedIdsMap = new HashMap<>();

        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();

        if (Objects.nonNull(inventoryMap)) {
            //库存校验
            ConfirmForecastResponse inventoryCheckResp = inventoryCheckNew(forecastOrderLineSDOList, inventoryMap);
            if (MapUtils.isNotEmpty(inventoryCheckResp.getFailOrderLineMap())) {
                log.info("批量确认-库存校验失败" + JSON.toJSONString(inventoryCheckResp));
                return inventoryCheckResp;
            }
        }

        Boolean[] isNeedCallParticipateActivity = new Boolean[1];
        isNeedCallParticipateActivity[0] = true;
        //start
        //子单 id 与子单的映射
        Map<String, ForecastOrderLineSDO> subOrderIdMap = forecastOrderLineSDOList.stream().collect(Collectors.toMap(subOrder -> subOrder.getId().toString(), Function.identity()));
        //占用活动
        log.info("ForecastOrderEntity#confirmCheckForecastNew forecastOrderLineSDOList:{}; isNeedCallParticipateActivity:{}; confirmForecastRequest:{}",
                JSONObject.toJSONString(forecastOrderLineSDOList), JSONObject.toJSONString(isNeedCallParticipateActivity), JSONObject.toJSONString(confirmForecastRequest));
        ParticipateInActivityResponse inActivityResponse = occupyActivity(forecastOrderLineSDOList, isNeedCallParticipateActivity, confirmForecastRequest);
        log.info("ForecastOrderEntity#confirmCheckForecastNew inActivityResponse:{}; forecastOrderLineSDOList:{}; isNeedCallParticipateActivity:{}; confirmForecastRequest:{}",
                JSONObject.toJSONString(inActivityResponse), JSONObject.toJSONString(forecastOrderLineSDOList), JSONObject.toJSONString(isNeedCallParticipateActivity), JSONObject.toJSONString(confirmForecastRequest));
        if (isNeedCallParticipateActivity[0]) {
            if (Objects.nonNull(inActivityResponse)
                    && CollectionUtils.isNotEmpty(inActivityResponse.getParticipateActivityResponseList())) {

                List<ParticipateActivityInfoResponse> participateActivityResponseList = inActivityResponse.getParticipateActivityResponseList();
                Map<String, List<ParticipateActivityInfoResponse>> participateActivityInfoResponseMap = participateActivityResponseList.stream()
                        .collect(Collectors.groupingBy(e -> e.getSubOrderId()));

                for (String subId : participateActivityInfoResponseMap.keySet()) {
                    ForecastOrderLineSDO forecastOrderLine = subOrderIdMap.get(subId);
                    Map<String, Object> features = forecastOrderLine.getFeatures() == null ? new HashMap<>() : forecastOrderLine.getFeatures();
                    List<ParticipateActivityInfoResponse> participateActivityInfoResponses = participateActivityInfoResponseMap.get(subId);
                    //活动返回值集合中有为false 的则为失败
                    List<ParticipateActivityInfoResponse> panduan = participateActivityInfoResponses.stream().filter(i ->
                            !i.getParticipateResult()).collect(Collectors.toList());
                    log.info("panduan活动结果:{}",JSON.toJSONString(panduan));
                    if (CollectionUtils.isNotEmpty(panduan)) {
                        Map<String, String> activityFailed = panduan.stream().collect(Collectors.toMap(ParticipateActivityInfoResponse::getSubOrderId, ParticipateActivityInfoResponse::getParticipateResultMsg, (v1, v2) -> v1));

                        ConfirmForecastResponse forecastResponse = new ConfirmForecastResponse();
                        Map<String, String> fail = new HashMap<>();
                        fail.put(subId, activityFailed.get(subId));
                        forecastResponse.setMessage(activityFailed.get(subId));
                        forecastResponse.setFailOrderLineMap(fail);
                        //更新子单的失败信息,是否可以先暂时不更新 todo 黔雷
//                        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
//                            //判断子订单是否需要经过活动检查
//                                backForecastUpdate(forecastOrderLineSDO, "异常情况活动占用失败！");
//                        }
//                        List<ConfirmForecastResponse> confirmForecastResponseYuan=new ArrayList<>();
                        log.info("批量确认-活动校验失败" + JSON.toJSONString(forecastResponse));
                        return forecastResponse;
                    }

                    //补全 feature 中的字段，原因一个字段对应多个不同类型的活动，需要添加不同的字段信息
                    for (ParticipateActivityInfoResponse participateActivityInfoResponse : participateActivityInfoResponses) {
                        if (participateActivityInfoResponse.getParticipateResult()) {
                            if (ActivityTypeEnum.SPECIAL_OFFER_PRICE.getValue().equals(participateActivityInfoResponse.getActivityType())) {
                                //特价活动添加占用活动成功的原品数量
                                features.put(ForecastConstants.ACTIVITY_INVENTORY, participateActivityInfoResponse.getParticipateSuccessItemCount());

                            }
//                        该字段会被覆盖，属于正常情况
                            features.put(ForecastConstants.CONFIRM_MESSAGE, participateActivityInfoResponse.getParticipateResultMsg());
                            successIdsMap.put(subId, participateActivityInfoResponse.getParticipateResultMsg());
                        }
                    }
                    //活动检查通过  获取活动量
                    forecastOrderLine.setFeatures(features);
                    forecastOrderLineWriteRepository.update(forecastOrderLine);

                    updateDealQueueStatus(forecastOrderLine);
                    successIds.add(subId);
                    if (!successIdsMap.containsKey(subId)) {
                        successIdsMap.put(subId, "确认成功");
                    }
                }
            } else {
                //异常情况活动占用失败！更新子单的失败信息
                for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                    failedIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                    confirmForecastResponse.setMessage(ACTIVITY_OCCUPY_EXCEPTION);
                    failedIdsMap.put(String.valueOf(forecastOrderLineSDO.getId()), ACTIVITY_OCCUPY_EXCEPTION);
                    confirmForecastResponse.setFailOrderLineMap(failedIdsMap);
                    //判断子订单是否需要经过活动检查, todo qjg 如果把这个注释掉，失败的预报子单也就无法推进到终态了
//                    if (StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode())) {
//                        backForecastUpdate(forecastOrderLineSDO, "异常情况活动占用失败！");
//                    }
                }
                return confirmForecastResponse;
            }
        }

        //库存校验成功的，没有活动的子单
        forecastOrderLineSDOList.forEach(forecastOrderLineSDO -> {
            Map<String, Object> features = forecastOrderLineSDO.getFeatures();
            if (StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode()) && MapUtils.isNotEmpty(features) && Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))) {
                List<ActivitySDO> activitySDOList = JSONObject.parseArray(JSON.toJSONString(features.get(ForecastConstants.ACTIVITY_DETAILS)), ActivitySDO.class);
                List<ActivitySDO> activitySDOS = activitySDOList.stream().filter(activitySDO -> activitySDO.getIsSelect() == true).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(activitySDOS)) {
                    successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                    successIdsMap.put(String.valueOf(forecastOrderLineSDO.getId()), "确认成功");
                }
            }

            if (StringUtils.isEmpty(forecastOrderLineSDO.getActivityCode())) {
                successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                successIdsMap.put(String.valueOf(forecastOrderLineSDO.getId()), "确认成功");
            }
        });

//        failedForecastResponse.setIds(failedIds);
//        success.setIds(successIds);
//        isCredit.setIds(creditIds);
//        confirmForecastResponses.add(isCredit);
//        confirmForecastResponses.add(success);
//        confirmForecastResponses.add(failedForecastResponse);
        confirmForecastResponse.setFailOrderLineMap(failedIdsMap);
        confirmForecastResponse.setSuccessOrderLineMap(successIdsMap);
        return confirmForecastResponse;
    }

    public ConfirmForecastResponse syncConfirmCheckForecastNew(ConfirmForecastRequest confirmForecastRequest, Map<String, String> inventoryMap) {

        ConfirmForecastResponse confirmForecastResponse = new ConfirmForecastResponse();
        List<String> successIds = new ArrayList<>();
        List<String> failedIds = new ArrayList<>();
        Map<String, String> successIdsMap = new HashMap<>();
        Map<String, String> failedIdsMap = new HashMap<>();
//        List<String> creditIds = new ArrayList<>();
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        //添加库存校验

        ConfirmForecastResponse inventoryCheckResp = syncInventoryCheckNew(forecastOrderLineSDOList,inventoryMap);
        if (MapUtils.isNotEmpty(inventoryCheckResp.getFailOrderLineMap())) {
            log.info("批量确认-库存校验失败" + JSON.toJSONString(inventoryCheckResp));
            return inventoryCheckResp;
        }
        Boolean[] isNeedCallParticipateActivity = new Boolean[1];
        isNeedCallParticipateActivity[0] = true;
        //start
        String sequenceNo = confirmForecastRequest.getSequenceNo();
        //子单 id 与子单的映射
        Map<String, ForecastOrderLineSDO> subOrderIdMap = forecastOrderLineSDOList.stream().collect(Collectors.toMap(subOrder -> StringUtils.joinWith("-", subOrder.getMainOrderBizId(),subOrder.getSerialNumber()), Function.identity()));
        //占用活动
        ParticipateInActivityResponse inActivityResponse = syncOccupyActivity(forecastOrderLineSDOList, isNeedCallParticipateActivity, sequenceNo);
        if (isNeedCallParticipateActivity[0]) {
            if (Objects.nonNull(inActivityResponse)
                    && CollectionUtils.isNotEmpty(inActivityResponse.getParticipateActivityResponseList())) {

                List<ParticipateActivityInfoResponse> participateActivityResponseList = inActivityResponse.getParticipateActivityResponseList();
                Map<String, List<ParticipateActivityInfoResponse>> participateActivityInfoResponseMap = participateActivityResponseList.stream()
                        .collect(Collectors.groupingBy(ParticipateActivityInfoResponse::getSubOrderId));

                for (String lineGroupKey : participateActivityInfoResponseMap.keySet()) {
                    ForecastOrderLineSDO forecastOrderLine = subOrderIdMap.get(lineGroupKey);
                    String subId=String.valueOf(forecastOrderLine.getId());
                    Map<String, Object> features = forecastOrderLine.getFeatures() == null ? new HashMap<>() : forecastOrderLine.getFeatures();
                    List<ParticipateActivityInfoResponse> participateActivityInfoResponses = participateActivityInfoResponseMap.get(lineGroupKey);
                    //活动返回值集合中有为false 的则为失败
                    List<ParticipateActivityInfoResponse> panduan = participateActivityInfoResponses.stream().filter(i ->
                            !i.getParticipateResult()).collect(Collectors.toList());
                    log.info("panduan活动结果:{}",JSON.toJSONString(panduan));
                    if (CollectionUtils.isNotEmpty(panduan)) {
                        Map<String, String> activityFailed = panduan.stream().collect(Collectors.toMap(ParticipateActivityInfoResponse::getSubOrderId, ParticipateActivityInfoResponse::getParticipateResultMsg, (v1, v2) -> v1));

                        ConfirmForecastResponse forecastResponse = new ConfirmForecastResponse();
                        Map<String, String> fail = new HashMap<>();
                        fail.put(subId, activityFailed.get(lineGroupKey));
                        forecastResponse.setMessage(activityFailed.get(lineGroupKey));
                        forecastResponse.setFailOrderLineMap(fail);
                        //更新子单的失败信息,是否可以先暂时不更新 todo 黔雷
//                        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
//                            //判断子订单是否需要经过活动检查
//                                backForecastUpdate(forecastOrderLineSDO, "异常情况活动占用失败！");
//                        }
//                        List<ConfirmForecastResponse> confirmForecastResponseYuan=new ArrayList<>();
                        log.info("批量确认-活动校验失败" + JSON.toJSONString(forecastResponse));
                        return forecastResponse;
                    }

                    //补全 feature 中的字段，原因一个字段对应多个不同类型的活动，需要添加不同的字段信息
                    for (ParticipateActivityInfoResponse participateActivityInfoResponse : participateActivityInfoResponses) {
                        if (participateActivityInfoResponse.getParticipateResult()) {
                            if (ActivityTypeEnum.SPECIAL_OFFER_PRICE.getValue().equals(participateActivityInfoResponse.getActivityType())) {
                                //特价活动添加占用活动成功的原品数量
                                features.put(ForecastConstants.ACTIVITY_INVENTORY, participateActivityInfoResponse.getParticipateSuccessItemCount());

                            }
//                        该字段会被覆盖，属于正常情况
                            features.put(ForecastConstants.CONFIRM_MESSAGE, participateActivityInfoResponse.getParticipateResultMsg());
                            successIdsMap.put(subId, participateActivityInfoResponse.getParticipateResultMsg());
                        }
                    }
                    //活动检查通过  获取活动量
                    forecastOrderLine.setFeatures(features);
                    forecastOrderLineWriteRepository.update(forecastOrderLine);

                    updateDealQueueStatus(forecastOrderLine);
                    successIds.add(subId);
                    if (!successIdsMap.containsKey(subId)) {
                        successIdsMap.put(subId, "确认成功");
                    }
                }
            } else {
                //异常情况活动占用失败！更新子单的失败信息
                for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                    failedIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                    confirmForecastResponse.setMessage(ACTIVITY_OCCUPY_EXCEPTION);
                    failedIdsMap.put(String.valueOf(forecastOrderLineSDO.getId()), ACTIVITY_OCCUPY_EXCEPTION);
                    confirmForecastResponse.setFailOrderLineMap(failedIdsMap);
                    //判断子订单是否需要经过活动检查, todo qjg 如果把这个注释掉，失败的预报子单也就无法推进到终态了
//                    if (StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode())) {
//                        backForecastUpdate(forecastOrderLineSDO, "异常情况活动占用失败！");
//                    }
                }
                return confirmForecastResponse;
            }
        }

        //库存校验成功的，没有活动的子单
        forecastOrderLineSDOList.forEach(forecastOrderLineSDO -> {
            Map<String, Object> features = forecastOrderLineSDO.getFeatures();
            if (StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode()) && MapUtils.isNotEmpty(features) && Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))) {
                List<ActivitySDO> activitySDOList = JSONObject.parseArray(JSON.toJSONString(features.get(ForecastConstants.ACTIVITY_DETAILS)), ActivitySDO.class);
                List<ActivitySDO> activitySDOS = activitySDOList.stream().filter(activitySDO -> activitySDO.getIsSelect() == true).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(activitySDOS)) {
                    successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                    successIdsMap.put(String.valueOf(forecastOrderLineSDO.getId()), "确认成功");
                }
            }

            if (StringUtils.isEmpty(forecastOrderLineSDO.getActivityCode())) {
                successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                successIdsMap.put(String.valueOf(forecastOrderLineSDO.getId()), "确认成功");
            }
        });

//        failedForecastResponse.setIds(failedIds);
//        success.setIds(successIds);
//        isCredit.setIds(creditIds);
//        confirmForecastResponses.add(isCredit);
//        confirmForecastResponses.add(success);
//        confirmForecastResponses.add(failedForecastResponse);
        confirmForecastResponse.setFailOrderLineMap(failedIdsMap);
        confirmForecastResponse.setSuccessOrderLineMap(successIdsMap);
        return confirmForecastResponse;
    }

    /**
     * 更新处理队列中的活动状态 ，当前方法更新为"确认完成"状态
     *
     * @param forecastOrderLineSDO1
     */
    private void updateDealQueueStatus(ForecastOrderLineSDO forecastOrderLineSDO1) {
        DealLineSDO dealLineSDO = new DealLineSDO();
        dealLineSDO.setForecastOrderLineId(String.valueOf(forecastOrderLineSDO1.getId()));
        dealLineSDO.setDealType("2");
        Result<List<DealLineQueue>> listResult = dealLineQueryRepository.queryProgressQueueResult(dealLineSDO);

        //更新处理队列中的状态
        List<DealLineQueue> collect = Nullable.stream(listResult.getResult()).map(it -> {
            it.setDealTime(new Date());
            it.setDealStatus(ForecastDealStatusSEO.CONFIRM_ED.getStatus());
            return it;
        }).collect(Collectors.toList());
//        TODO 袁登优化
        for (DealLineQueue dealLineQueue : collect) {
            boolean b = dealLineWriteRepository.update(dealLineQueue);
        }
    }

    @Deprecated
    private List<ConfirmForecastResponse> inventoryCheck(List<ForecastOrderLineSDO> forecastOrderLineSDOList) {
        List<ConfirmForecastResponse> confirmForecastResponses = new ArrayList<>();
        ConfirmForecastResponse success = new ConfirmForecastResponse();
        //成功
        success.setTag("1");
        ConfirmForecastResponse failed = new ConfirmForecastResponse();
        //失败
        failed.setTag("2");
        List<String> successIds = new ArrayList<>();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            QueryAvailableInventoryRequest queryAvailableInventoryRequest = new QueryAvailableInventoryRequest();
            queryAvailableInventoryRequest.setType("1");
            queryAvailableInventoryRequest.setWarehouseAreaId(forecastOrderSDO.getWareHouseCode());
            queryAvailableInventoryRequest.setGoodsId(forecastOrderLineSDO.getScItemId());
            log.info("查询仓库库存入参：{}", JSONObject.toJSONString(queryAvailableInventoryRequest));
            BigDecimal inventory = BigDecimal.valueOf(forecastOrderQueryRepository.queryInventory(queryAvailableInventoryRequest)).setScale(3, RoundingMode.DOWN);
////            Integer inventory=10000;
//            Map<String, Object> features=forecastOrderLineSDO.getFeatures()==null?new HashMap<>():forecastOrderLineSDO.getFeatures();
            BigDecimal predictReplyAmount = forecastOrderLineSDO.getPredictReplyAmount() == null ? BigDecimal.ZERO : new BigDecimal(forecastOrderLineSDO.getPredictReplyAmount()).divide(new BigDecimal(forecastOrderLineSDO.getUnitConvert()), 3, RoundingMode.DOWN).setScale(3, RoundingMode.DOWN);
            if (predictReplyAmount.compareTo(inventory) > 0) {
                List<ConfirmForecastResponse> confirmForecastResponses1 = new ArrayList<>();
                backForecastUpdate(forecastOrderLineSDO, "库存不足不可以生成销售订单！");
                //主要是为了返回空对象列表
                return confirmForecastResponses1;
            }
            successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
        }
        success.setIds(successIds);
        confirmForecastResponses.add(success);
        return confirmForecastResponses;
    }

    private ConfirmForecastResponse inventoryCheckNew(List<ForecastOrderLineSDO> forecastOrderLineSDOList, Map<String, String> inventoryMap) {
        ConfirmForecastResponse forecastResponse = new ConfirmForecastResponse();
        //成功
        //        forecastResponse.setTag("1");
        Map<String, String> success = new HashMap<>();
        Map<String, String> fail = new HashMap<>();
        //库存范围精度
        BigDecimal precisionRange=BigDecimal.ZERO;
        //add by myw at 20230210 for 库存不校验配置 end
        String organizationCode = forecastOrderSDO.getOrganizationCode();
        StrategyPageQueryRequest moreConditionQueryRequest = new StrategyPageQueryRequest();
        moreConditionQueryRequest.setType(StrategyTypeEnum.INVENTORY_VALID.getCode());
        moreConditionQueryRequest.setOrganizationCode(organizationCode);//forecastOrderSDO.getOrganizationCode()
        try {
            Result<List<StrategyPageQueryResponse>> moreConditionQueryResponseResult = strategyQueryService.pageQuery(moreConditionQueryRequest);
            if (Objects.nonNull(moreConditionQueryResponseResult)&&CollectionUtils.isNotEmpty(moreConditionQueryResponseResult.getResult())){
                for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                    success.put(String.valueOf(forecastOrderLineSDO.getId()), "成功");
                }
                forecastResponse.setFailOrderLineMap(fail);
                forecastResponse.setSuccessOrderLineMap(success);
                log.info("预报订单确认库存校验，预报单:{},命中库存不检查策略:{},跳过库存校验",forecastOrderSDO.getOrderBizId(),moreConditionQueryResponseResult.getResult().get(0).getStrategyName());
                return forecastResponse;
            }
        }catch (Throwable e){
            log.error("预报订单确认库存校验，预报单:{},查询库存不检查异常,{}",forecastOrderSDO.getOrderBizId(),e);
        }

        //add by myw,at 20230228 for 库存补差配置 end
        StrategyPageQueryRequest strategyPageQueryRequest = new StrategyPageQueryRequest();
        strategyPageQueryRequest.setOrganizationCode(organizationCode);
        strategyPageQueryRequest.setStatus(1);//有效的策略
        strategyPageQueryRequest.setType(StrategyTypeEnum.INVENTORY_RANGE.getCode());//查询优先回复策略
        log.info("查询库存补差入参" + JSONObject.toJSONString(strategyPageQueryRequest));
        try {

            Result<List<StrategyPageQueryResponse>> listResult = strategyQueryService.pageQuery(strategyPageQueryRequest);
            log.info("查询库存补差出参" + JSONObject.toJSONString(listResult));
            if (Objects.nonNull(listResult)&&CollectionUtils.isNotEmpty(listResult.getResult())){
                //查询组织策略详情
                StrategyQueryByIdRequest channelRequest = new StrategyQueryByIdRequest();
                channelRequest.setId(listResult.getResult().get(0).getId());
                channelRequest.setStatus("0");
                channelRequest.setCode(DimensionTypeEnum.ORGANIZE.getCode());
                log.info("查询库存补差详情入参" + JSONObject.toJSONString(channelRequest));
                Result<StrategyQueryByIdResponse> channelResponseResult = strategyQueryService.queryById(channelRequest);
                log.info("查询库存补差详情出参" + JSONObject.toJSONString(channelResponseResult));
                if (Objects.nonNull(channelResponseResult.getResult())
                        && Objects.nonNull(channelResponseResult.getResult().getStrategySDO())) {
                    List<DimensionSDO> dimensionSDOS = channelResponseResult.getResult().getStrategySDO().getDimensionSDOList();
                    if (CollectionUtils.isEmpty(dimensionSDOS)) {
                        log.warn("查询库存补差策略详情维度为空{}", forecastOrderSDO.getId());
                        throw new RuntimeException("查询库存补差策略详情维度为空");
                    }
                    for (DimensionSDO dimensionSDO : dimensionSDOS) {
                        //主单ID-库存精度范围
                        String value = dimensionSDO.getValue();
                        if (StringUtils.isNotBlank(value)&&dimensionSDO.getStatus().equals("0")) {
                            long startTime = dimensionSDO.getValidBeginTime().getTime();
                            long endTime = dimensionSDO.getValidEndTime().getTime();
                            long nowTime = new Date().getTime();
                            if (startTime<=nowTime&&nowTime<=endTime ){
                                precisionRange = new BigDecimal(value).divide(BigDecimal.valueOf(100),3, RoundingMode.HALF_UP);
                                break;
                            }
                        }
                    }
                }
                log.info("预报订单确认库存校验，预报单:{},命中库存补差策略:{},补差值{}",forecastOrderSDO.getOrderBizId(),listResult.getResult().get(0).getStrategyName(),precisionRange);
            }
        }catch (Throwable e){
            log.error("预报订单确认库存校验，预报单:{},查询库存补差策略异常,{}",forecastOrderSDO.getOrderBizId(),e);
        }
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            String inventoryKey = String.format("%s-%s", forecastOrderSDO.getWareHouseCode(), forecastOrderLineSDO.getScItemId());

            BigDecimal predictReplyAmount = forecastOrderLineSDO.getPredictReplyAmount() == null ? BigDecimal.ZERO : new BigDecimal(forecastOrderLineSDO.getPredictReplyAmount()).divide(new BigDecimal(forecastOrderLineSDO.getUnitConvert()), 3, RoundingMode.HALF_UP);

            Map features = forecastOrderLineSDO.getFeatures();
            List<ActivitySDO> activitySDOS = new ArrayList<>();
            if (Objects.nonNull(features) && Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))) {
                activitySDOS = JSONObject.parseArray(JSON.toJSONString(features.get(ForecastConstants.ACTIVITY_DETAILS)), ActivitySDO.class);
            }
            for (ActivitySDO activitySDO : activitySDOS) {

                if (Objects.nonNull(activitySDO) && Objects.nonNull(activitySDO.getIsSelect()) && activitySDO.getIsSelect()) {
                    //add by myw,20230103,赠品库存校验（套餐活动只校验主子单行赠品库存）
                    if (Objects.nonNull(activitySDO.getDisableChooseFlag())&&activitySDO.getDisableChooseFlag()){
                        continue;
                    }
                    List<GiftSDO> chooseGiftList = activitySDO.getChooseGiftList();
                    if (CollectionUtils.isNotEmpty(chooseGiftList)) {
                        for (GiftSDO giftSDO : chooseGiftList) {
                            String giftSDOScItemId = giftSDO.getScItemId();
                            BigDecimal giftNumberBase;
                            if (giftSDO.getGiftNumber() == null) {
                                giftNumberBase = BigDecimal.ZERO;
                            } else {
                                String conversionUnit = StringUtils.isBlank(giftSDO.getConversionUnit()) ? "1" : giftSDO.getConversionUnit();
                                giftNumberBase = new BigDecimal(giftSDO.getGiftNumber()).divide(new BigDecimal(conversionUnit), 3, RoundingMode.HALF_UP).setScale(3, RoundingMode.HALF_UP);
                            }

                            String giftInventoryKey = String.format("%s-%s", forecastOrderSDO.getWareHouseCode(), giftSDOScItemId);
                            BigDecimal giftInventory = new BigDecimal(inventoryMap.getOrDefault(giftInventoryKey, "0")).setScale(3,RoundingMode.HALF_UP);
                            //考虑库存补差后的库存
                            BigDecimal afterRangeGiftInventory=giftInventory.multiply(BigDecimal.ONE.add(precisionRange)).setScale(3,RoundingMode.HALF_UP);
                            if (giftNumberBase.compareTo(afterRangeGiftInventory) > 0) {
                                fail.put(String.valueOf(forecastOrderLineSDO.getId()), INVENTORY_CHECK_FAIL);
                                forecastResponse.setMessage(INVENTORY_CHECK_FAIL);
                                //主要是为了返回空对象列表
                                forecastResponse.setFailOrderLineMap(fail);
                                return forecastResponse;
                            }
                            String giftInventoryFloatStr=giftInventory.subtract(giftNumberBase).toString();
                            inventoryMap.put(giftInventoryKey,giftInventoryFloatStr);
                        }
                    }
                }
            }
            BigDecimal inventory = new BigDecimal(inventoryMap.getOrDefault(inventoryKey, "0")).setScale(3,RoundingMode.HALF_UP);
            //考虑库存补差后的库存
            BigDecimal afterRangeInventory=inventory.multiply(BigDecimal.ONE.add(precisionRange)).setScale(3,RoundingMode.HALF_UP);
            if (predictReplyAmount.compareTo(afterRangeInventory) > 0) {
                fail.put(String.valueOf(forecastOrderLineSDO.getId()), INVENTORY_CHECK_FAIL);
                forecastResponse.setMessage(INVENTORY_CHECK_FAIL);
                //主要是为了返回空对象列表
                forecastResponse.setFailOrderLineMap(fail);
                return forecastResponse;
            }
            String inventoryFloatStr=inventory.subtract(predictReplyAmount).toString();
            inventoryMap.put(inventoryKey,inventoryFloatStr);
            success.put(String.valueOf(forecastOrderLineSDO.getId()), "成功");

        }
        forecastResponse.setFailOrderLineMap(fail);
        forecastResponse.setSuccessOrderLineMap(success);
        return forecastResponse;
    }


    private ConfirmForecastResponse syncInventoryCheckNew(List<ForecastOrderLineSDO> forecastOrderLineSDOList, Map<String, String> inventoryMap) {
        ConfirmForecastResponse forecastResponse = new ConfirmForecastResponse();
        //成功
        //        forecastResponse.setTag("1");
        Map<String, String> success = new HashMap<>();
        Map<String, String> fail = new HashMap<>();
        //库存范围精度
        BigDecimal precisionRange=BigDecimal.ZERO;
        //add by myw at 20230210 for 库存不校验配置 end
        String organizationCode = forecastOrderSDO.getOrganizationCode();
        StrategyPageQueryRequest moreConditionQueryRequest = new StrategyPageQueryRequest();
        moreConditionQueryRequest.setType(StrategyTypeEnum.INVENTORY_VALID.getCode());
        moreConditionQueryRequest.setOrganizationCode(organizationCode);//forecastOrderSDO.getOrganizationCode()
        try {
            Result<List<StrategyPageQueryResponse>> moreConditionQueryResponseResult = strategyQueryService.pageQuery(moreConditionQueryRequest);
            if (Objects.nonNull(moreConditionQueryResponseResult)&&CollectionUtils.isNotEmpty(moreConditionQueryResponseResult.getResult())){
                for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                    success.put(String.valueOf(forecastOrderLineSDO.getId()), "成功");
                }
                forecastResponse.setFailOrderLineMap(fail);
                forecastResponse.setSuccessOrderLineMap(success);
                log.info("预报订单确认库存校验，预报单:{},命中库存不检查策略:{},跳过库存校验",forecastOrderSDO.getOrderBizId(),moreConditionQueryResponseResult.getResult().get(0).getStrategyName());
                return forecastResponse;
            }
        }catch (Throwable e){
            log.error("预报订单确认库存校验，预报单:{},查询库存不检查异常,{}",forecastOrderSDO.getOrderBizId(),e);
        }

        //add by myw,at 20230228 for 库存补差配置 end
        StrategyPageQueryRequest strategyPageQueryRequest = new StrategyPageQueryRequest();
        strategyPageQueryRequest.setOrganizationCode(organizationCode);
        strategyPageQueryRequest.setStatus(1);//有效的策略
        strategyPageQueryRequest.setType(StrategyTypeEnum.INVENTORY_RANGE.getCode());//查询优先回复策略
        log.info("查询库存补差入参" + JSONObject.toJSONString(strategyPageQueryRequest));
        try {

            Result<List<StrategyPageQueryResponse>> listResult = strategyQueryService.pageQuery(strategyPageQueryRequest);
            log.info("查询库存补差出参" + JSONObject.toJSONString(listResult));
            if (Objects.nonNull(listResult)&&CollectionUtils.isNotEmpty(listResult.getResult())){
                //查询组织策略详情
                StrategyQueryByIdRequest channelRequest = new StrategyQueryByIdRequest();
                channelRequest.setId(listResult.getResult().get(0).getId());
                channelRequest.setStatus("0");
                channelRequest.setCode(DimensionTypeEnum.ORGANIZE.getCode());
                log.info("查询库存补差详情入参" + JSONObject.toJSONString(channelRequest));
                Result<StrategyQueryByIdResponse> channelResponseResult = strategyQueryService.queryById(channelRequest);
                log.info("查询库存补差详情出参" + JSONObject.toJSONString(channelResponseResult));
                if (Objects.nonNull(channelResponseResult.getResult())
                        && Objects.nonNull(channelResponseResult.getResult().getStrategySDO())) {
                    List<DimensionSDO> dimensionSDOS = channelResponseResult.getResult().getStrategySDO().getDimensionSDOList();
                    if (CollectionUtils.isEmpty(dimensionSDOS)) {
                        log.warn("查询库存补差策略详情维度为空{}", forecastOrderSDO.getId());
                        throw new RuntimeException("查询库存补差策略详情维度为空");
                    }
                    for (DimensionSDO dimensionSDO : dimensionSDOS) {
                        //主单ID-库存精度范围
                        String value = dimensionSDO.getValue();
                        if (StringUtils.isNotBlank(value)&&dimensionSDO.getStatus().equals("0")) {
                            long startTime = dimensionSDO.getValidBeginTime().getTime();
                            long endTime = dimensionSDO.getValidEndTime().getTime();
                            long nowTime = new Date().getTime();
                            if (startTime<=nowTime&&nowTime<=endTime ){
                                precisionRange = new BigDecimal(value).divide(BigDecimal.valueOf(100),3, RoundingMode.HALF_UP);
                                break;
                            }
                        }
                    }
                }
                log.info("预报订单确认库存校验，预报单:{},命中库存补差策略:{},补差值{}",forecastOrderSDO.getOrderBizId(),listResult.getResult().get(0).getStrategyName(),precisionRange);
            }
        }catch (Throwable e){
            log.error("预报订单确认库存校验，预报单:{},查询库存补差策略异常,{}",forecastOrderSDO.getOrderBizId(),e);
        }

        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            String inventoryKey = String.format("%s-%s", forecastOrderSDO.getWareHouseCode(), forecastOrderLineSDO.getScItemId());

            BigDecimal predictReplyAmount = forecastOrderLineSDO.getPredictReplyAmount() == null ? BigDecimal.ZERO : new BigDecimal(forecastOrderLineSDO.getPredictReplyAmount()).divide(new BigDecimal(forecastOrderLineSDO.getUnitConvert()), 3, RoundingMode.HALF_UP);

            Map features = forecastOrderLineSDO.getFeatures();
            List<ActivitySDO> activitySDOS = new ArrayList<>();
            if (Objects.nonNull(features) && Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))) {
                activitySDOS = JSONObject.parseArray(JSON.toJSONString(features.get(ForecastConstants.ACTIVITY_DETAILS)), ActivitySDO.class);
            }
            for (ActivitySDO activitySDO : activitySDOS) {

                if (Objects.nonNull(activitySDO) && Objects.nonNull(activitySDO.getIsSelect()) && activitySDO.getIsSelect()) {
                    //add by myw,20230103,赠品库存校验（套餐活动只校验主子单行赠品库存）
                    if (Objects.nonNull(activitySDO.getDisableChooseFlag())&&activitySDO.getDisableChooseFlag()){
                        continue;
                    }
                    List<GiftSDO> chooseGiftList = activitySDO.getChooseGiftList();
                    if (CollectionUtils.isNotEmpty(chooseGiftList)) {
                        List<String> goodsCodes = chooseGiftList.stream().map(GiftSDO::getScItemId).collect(Collectors.toList());
                        Map<String, String> scItemIdMap = queryScItemIdMap(goodsCodes);
                        for (GiftSDO giftSDO : chooseGiftList) {
                            String giftSDOScItemCode = giftSDO.getScItemId();
                            String giftSDOScItemId = scItemIdMap.get(giftSDOScItemCode);
                            BigDecimal giftNumberBase;
                            if (giftSDO.getGiftNumber() == null) {
                                giftNumberBase = BigDecimal.ZERO;
                            } else {
                                String conversionUnit = StringUtils.isBlank(giftSDO.getConversionUnit()) ? "1" : giftSDO.getConversionUnit();
                                giftNumberBase = new BigDecimal(giftSDO.getGiftNumber()).divide(new BigDecimal(conversionUnit), 3, RoundingMode.HALF_UP).setScale(3, RoundingMode.HALF_UP);
                            }

                            String giftInventoryKey = String.format("%s-%s", forecastOrderSDO.getWareHouseCode(), giftSDOScItemId);
                            BigDecimal giftInventory = new BigDecimal(inventoryMap.getOrDefault(giftInventoryKey, "0")).setScale(3,RoundingMode.HALF_UP);
                            //考虑库存补差后的库存
                            BigDecimal afterRangeGiftInventory=giftInventory.multiply(BigDecimal.ONE.add(precisionRange)).setScale(3,RoundingMode.HALF_UP);
                            if (giftNumberBase.compareTo(afterRangeGiftInventory) > 0) {
                                fail.put(String.valueOf(forecastOrderLineSDO.getId()), INVENTORY_CHECK_FAIL);
                                forecastResponse.setMessage(INVENTORY_CHECK_FAIL);
                                //主要是为了返回空对象列表
                                forecastResponse.setFailOrderLineMap(fail);
                                return forecastResponse;
                            }
                            String giftInventoryFloatStr=giftInventory.subtract(giftNumberBase).toString();
                            inventoryMap.put(giftInventoryKey,giftInventoryFloatStr);
                        }
                    }
                }
            }
            BigDecimal inventory = new BigDecimal(inventoryMap.getOrDefault(inventoryKey, "0")).setScale(3,RoundingMode.HALF_UP);
            //考虑库存补差后的库存
            BigDecimal afterRangeInventory=inventory.multiply(BigDecimal.ONE.add(precisionRange)).setScale(3,RoundingMode.HALF_UP);
            if (predictReplyAmount.compareTo(afterRangeInventory) > 0) {
                fail.put(String.valueOf(forecastOrderLineSDO.getId()), INVENTORY_CHECK_FAIL);
                forecastResponse.setMessage(INVENTORY_CHECK_FAIL);
                //主要是为了返回空对象列表
                forecastResponse.setFailOrderLineMap(fail);
                return forecastResponse;
            }
            String inventoryFloatStr=inventory.subtract(predictReplyAmount).toString();
            inventoryMap.put(inventoryKey,inventoryFloatStr);
            success.put(String.valueOf(forecastOrderLineSDO.getId()), "成功");

        }
        forecastResponse.setFailOrderLineMap(fail);
        forecastResponse.setSuccessOrderLineMap(success);
        return forecastResponse;
    }

    @NotNull
    private Map<String, String> queryScItemIdMap(List<String> goodsCodes) {
        SearchScItemByDBWhenDegradedRequest searchScItemRequest = new SearchScItemByDBWhenDegradedRequest();
        searchScItemRequest.setPageSize(pageSize);
        Map<String, Object> searchReqDTO = new HashMap<>();
        searchReqDTO.put("outerIdList", goodsCodes);

        searchScItemRequest.setSearchReqDTO(searchReqDTO);
        //支持es降级查询db
        Result<List<com.epoch.app.bcorder.model.dto.ScItemSDO>> scItemListResult = baseDataService.searchScItemByDBWhenDegraded(searchScItemRequest);
        if (Objects.isNull(scItemListResult)||CollectionUtils.isEmpty(scItemListResult.getResult())) {
            throw new FacadeException("OTS-08-001-01-16-021");
        }

        return  scItemListResult.getResult().stream().collect(Collectors.toMap(com.epoch.app.bcorder.model.dto.ScItemSDO::getOuterId, com.epoch.app.bcorder.model.dto.ScItemSDO::getScItemId));
    }

    /**
     * 确认校验失败，更新子弹处理状态
     *
     * @param forecastOrderLineSDO 子单
     * @param message              失败信息
     */
    public void backForecastUpdate(ForecastOrderLineSDO forecastOrderLineSDO, String message) {
        Map<String, Object> features = forecastOrderLineSDO.getFeatures() == null ?
                new HashMap<>() : forecastOrderLineSDO.getFeatures();
        features.put(ForecastConstants.CONFIRM_MESSAGE, message);
        forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.CONFIRM_ED.getStatus());
        forecastOrderLineSDO.setFeatures(features);
        forecastOrderLineWriteRepository.update(forecastOrderLineSDO);
//           todo 袁登
        updateDealQueueStatus(forecastOrderLineSDO);
    }

    /**
     * 该方法名字出校验活动，本质是参加活动（是扣减活动的剩余金额和活动剩余数量）
     *
     * @param forecastOrderLineSDOList      子单列表
     * @param isNeedCallParticipateActivity
     * @return 参加活动的结果
     */
    private ParticipateInActivityResponse occupyActivity(List<ForecastOrderLineSDO> forecastOrderLineSDOList, Boolean[] isNeedCallParticipateActivity, ConfirmForecastRequest confirmForecastRequest) {
        ParticipateActivityRequest participateActivityRequest = new ParticipateActivityRequest();
        List<ParticipateActivityInfoRequest> participateActivityInfoList = new ArrayList<>();
        //设置查询活动时的参数
        QueryActivityRequest queryActivityRequest = new QueryActivityRequest();
        List<ActivityInfoRequest> activityInfoRequestList = new ArrayList<>();

        Map<String, Map<Long, List<ActivitySDO>>> preOccupyActivityCheckMap = new HashMap<>();
        List<String> ids = forecastOrderLineSDOList.stream().map(o -> String.valueOf(o.getId())).collect(Collectors.toList());
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            Map<String, Object> features = forecastOrderLineSDO.getFeatures() == null ? new HashMap<>() : forecastOrderLineSDO.getFeatures();
            //判断子订单是否需要经过活动检查
            if (StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode())) {
                //添加活动参数
                List<ActivitySDO> activitySDOS = new ArrayList<>();
                if (Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))) {
                    activitySDOS = JSONObject.parseArray(JSON.toJSONString(features.get(ForecastConstants.ACTIVITY_DETAILS)), ActivitySDO.class);
                }
                Map<Long, List<ActivitySDO>> orDefault = preOccupyActivityCheckMap.getOrDefault(forecastOrderLineSDO.getMainOrderId(), new HashMap<>());
                orDefault.put(forecastOrderLineSDO.getId(), activitySDOS);
                preOccupyActivityCheckMap.put(forecastOrderLineSDO.getMainOrderId(), orDefault);

                //补货活动单独处理
                if (SaleOrderTag.REPLENISH_FORECAST.getCode().equals(this.forecastOrderSDO.getOrderType())) {
                    ActivitySDO activitySDO = new ActivitySDO();
                    Map<String, Object> features1 = forecastOrderLineSDO.getFeatures();
                    //feature 不为空，活动编码不为空，添加到活动列表中
                    if (MapUtils.isNotEmpty(features1)) {
                        Integer version = features1.get(ForecastConstants.REPLENISHMENT_ACTIVITY_VERSION) == null ? 0 :
                                Integer.parseInt(String.valueOf(features1.get(ForecastConstants.REPLENISHMENT_ACTIVITY_VERSION)));

                        String activityTermId = features1.get(ForecastConstants.ACTIVITY_NUMBER) == null ? "" :
                                String.valueOf(features1.get(ForecastConstants.ACTIVITY_NUMBER));
                        String activityCode = forecastOrderLineSDO.getActivityCode();
                        //更新成最新的活动版本
                        version = updateNewVersion(activitySDOS, activityCode, activityTermId, version);

                        //如果版本号或者活动的termId为空，直接遍历下一个子单
                        if (Objects.isNull(version) || version == 0 || StringUtils.isBlank(activityTermId)) {
                            continue;
                        }
                        activitySDO.setVersion(version);
                        activitySDO.setActivityTermid(activityTermId);
                        activitySDO.setActivityCode(activityCode);
                        activitySDO.setIsSelect(true);
                        activitySDOS.add(activitySDO);
                    }
                }

                for (ActivitySDO activitySDO : activitySDOS) {
                    if (Objects.isNull(activitySDO)
                            || Objects.isNull(activitySDO.getIsSelect())
                            || !activitySDO.getIsSelect()) {
                        continue;
                    }
                    //加入子单的查询活动入参
                    if (Objects.nonNull(features.get(ForecastConstants.ACTIVITY_CHECK_PARAMS))) {
                        ActivityInfoRequest activityInfoRequest = JSONObject.parseObject(JSONObject.toJSONString(features.get(ForecastConstants.ACTIVITY_CHECK_PARAMS)), ActivityInfoRequest.class);
                        activityInfoRequestList.add(activityInfoRequest);
                    } else {
                        ActivityInfoRequest activityInfoRequest = createActivityInfoRequest(forecastOrderLineSDO);
                        activityInfoRequestList.add(activityInfoRequest);
                    }

                    //参加活动的入参
//                    if (Objects.isNull(activitySDO.getDisableChooseFlag())||!activitySDO.getDisableChooseFlag()){
                    ParticipateActivityInfoRequest participateActivityInfoRequest = buildParticipateActivityInfoRequest(forecastOrderLineSDO, activitySDO, confirmForecastRequest.getSequenceNo(),false);
                    if (StringUtils.isNotBlank(confirmForecastRequest.getContent())) {
                        // 一盘货订单修改
                        log.info("ForecastOrderEntity#occupyActivity activitySDO:{}", JSON.toJSONString(activitySDO));
                        participateActivityInfoRequest=buildParticipateActivityInfoRequest(forecastOrderLineSDO,activitySDO, confirmForecastRequest.getSequenceNo(),true);
                    }
                    participateActivityInfoList.add(participateActivityInfoRequest);
//                    }
                }
            }
        }
        log.info("participateActivityInfoList结果:{}",JSON.toJSONString(participateActivityInfoList));
        ParticipateInActivityResponse checkFullBuyGift = checkFullBuyGift(preOccupyActivityCheckMap, ids);
        log.info("checkFullBuyGift结果:{}",JSON.toJSONString(checkFullBuyGift));
        if (CollectionUtils.isNotEmpty(checkFullBuyGift.getParticipateActivityResponseList())) {
            return checkFullBuyGift;
        }


        Map<String, String> map = new HashMap<>();
        //移除重复的查询活动请求数据
        activityInfoRequestList = removeRepeatActivityInfoRequest(activityInfoRequestList);

        String codeFlag = INNER_CODE_TO_OUT_CODE;
        if (StringUtils.isNotBlank(confirmForecastRequest.getContent())) {
            try {
                JSONObject content = JSON.parseObject(confirmForecastRequest.getContent());
                // 一盘货订单通过入参传入转码方式
                codeFlag = content.getString(CODE_FLAG);

                // 打标，用来区分活动校验逻辑
                map.put(OS, content.getString(OS));
            } catch (Exception e) {
                log.error("一盘货订单通过入参传入转码方式异常，默认使用内部转码方式", e);
            }
        }

        //查询活动请求封装
        queryActivityRequest.setActivityInfoRequestList(activityInfoRequestList);
        Map<String, String> features = new HashMap<>();
        features.put(CODE_FLAG, codeFlag);
        queryActivityRequest.setFeatures(features);
        //添加活动查询参数
        map.put(ADD_ACTIVITY_QUERY_PARAM, JSONObject.toJSONString(queryActivityRequest));
        //内外码转换
        map.put(CODE_FLAG, codeFlag);
        //预报订单号
        map.put(FORECAST_ORDER_BIZ_ID, forecastOrderSDO.getOrderBizId());
        //设置 feature
        participateActivityRequest.setFeatures(map);

        //设置参加活动参数列表
        participateActivityRequest.setParticipateActivityInfoList(participateActivityInfoList);
        //列表为空，不要调用
        if (CollectionUtils.isEmpty(participateActivityInfoList)) {
            ParticipateInActivityResponse participateInActivityResponse = new ParticipateInActivityResponse();
            isNeedCallParticipateActivity[0] = false;
            return participateInActivityResponse;
        }
        Result<ParticipateInActivityResponse> participateInActivityResponseResult = activityWriteService.participateActivityExpand(participateActivityRequest);
        log.info("participateInActivityResponseResult结果:{}",JSON.toJSONString(participateInActivityResponseResult));
        if (Objects.nonNull(participateInActivityResponseResult)
                && Objects.nonNull(participateInActivityResponseResult.getResult())
                && CollectionUtils.isNotEmpty(participateInActivityResponseResult.getResult().getParticipateActivityResponseList())) {

            if (participateInActivityResponseResult.isSuccess()) {
                return participateInActivityResponseResult.getResult();
            }
        }
        return null;
    }

    private ParticipateInActivityResponse syncOccupyActivity(List<ForecastOrderLineSDO> forecastOrderLineSDOList, Boolean[] isNeedCallParticipateActivity, String sequenceNo) {
        ParticipateActivityRequest participateActivityRequest = new ParticipateActivityRequest();
        List<ParticipateActivityInfoRequest> participateActivityInfoList = new ArrayList<>();
        //设置查询活动时的参数
        QueryActivityRequest queryActivityRequest = new QueryActivityRequest();
        List<ActivityInfoRequest> activityInfoRequestList = new ArrayList<>();

        Map<String, Map<Long, List<ActivitySDO>>> preOccupyActivityCheckMap = new HashMap<>();
        List<String> ids = forecastOrderLineSDOList.stream().map(o -> String.valueOf(o.getId())).collect(Collectors.toList());
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            Map<String, Object> features = forecastOrderLineSDO.getFeatures() == null ? new HashMap<>() : forecastOrderLineSDO.getFeatures();
            //判断子订单是否需要经过活动检查
            if (StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode())) {
                //添加活动参数
                List<ActivitySDO> activitySDOS = new ArrayList<>();
                if (Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))) {
                    activitySDOS = JSONObject.parseArray(JSON.toJSONString(features.get(ForecastConstants.ACTIVITY_DETAILS)), ActivitySDO.class);
                }
                Map<Long, List<ActivitySDO>> orDefault = preOccupyActivityCheckMap.getOrDefault(forecastOrderLineSDO.getMainOrderId(), new HashMap<>());
                orDefault.put(forecastOrderLineSDO.getId(), activitySDOS);
                preOccupyActivityCheckMap.put(forecastOrderLineSDO.getMainOrderId(), orDefault);

                //补货活动单独处理
                if (SaleOrderTag.REPLENISH_FORECAST.getCode().equals(this.forecastOrderSDO.getOrderType())) {
                    ActivitySDO activitySDO = new ActivitySDO();
                    Map<String, Object> features1 = forecastOrderLineSDO.getFeatures();
                    //feature 不为空，活动编码不为空，添加到活动列表中
                    if (MapUtils.isNotEmpty(features1)) {
                        Integer version = features1.get(ForecastConstants.REPLENISHMENT_ACTIVITY_VERSION) == null ? 0 :
                                Integer.parseInt(String.valueOf(features1.get(ForecastConstants.REPLENISHMENT_ACTIVITY_VERSION)));

                        String activityTermId = features1.get(ForecastConstants.ACTIVITY_NUMBER) == null ? "" :
                                String.valueOf(features1.get(ForecastConstants.ACTIVITY_NUMBER));
                        String activityCode = forecastOrderLineSDO.getActivityCode();
                        //更新成最新的活动版本
                        version = updateNewVersion(activitySDOS, activityCode, activityTermId, version);

                        //如果版本号或者活动的termId为空，直接遍历下一个子单
                        if (Objects.isNull(version) || version == 0 || StringUtils.isBlank(activityTermId)) {
                            continue;
                        }
                        activitySDO.setVersion(version);
                        activitySDO.setActivityTermid(activityTermId);
                        activitySDO.setActivityCode(activityCode);
                        activitySDO.setIsSelect(true);
                        activitySDOS.add(activitySDO);
                    }
                }

                for (ActivitySDO activitySDO : activitySDOS) {
                    if (Objects.isNull(activitySDO)
                            || Objects.isNull(activitySDO.getIsSelect())
                            || !activitySDO.getIsSelect()) {
                        continue;
                    }
                    //加入子单的查询活动入参
                    if (Objects.nonNull(features.get(ForecastConstants.ACTIVITY_CHECK_PARAMS))) {
                        ActivityInfoRequest activityInfoRequest = JSONObject.parseObject(JSONObject.toJSONString(features.get(ForecastConstants.ACTIVITY_CHECK_PARAMS)), ActivityInfoRequest.class);
                        activityInfoRequestList.add(activityInfoRequest);
                    } else {
                        ActivityInfoRequest activityInfoRequest = createActivityInfoRequest(forecastOrderLineSDO);
                        activityInfoRequestList.add(activityInfoRequest);
                    }

                    //参加活动的入参
//                    if (Objects.isNull(activitySDO.getDisableChooseFlag())||!activitySDO.getDisableChooseFlag()){
                    ParticipateActivityInfoRequest participateActivityInfoRequest = buildSyncParticipateActivityInfoRequest(forecastOrderLineSDO, activitySDO, sequenceNo);
                    participateActivityInfoList.add(participateActivityInfoRequest);
//                    }
                }
            }
        }
        log.info("participateActivityInfoList结果:{}",JSON.toJSONString(participateActivityInfoList));
        ParticipateInActivityResponse checkFullBuyGift = checkFullBuyGift(preOccupyActivityCheckMap, ids);
        log.info("checkFullBuyGift结果:{}",JSON.toJSONString(checkFullBuyGift));
        if (CollectionUtils.isNotEmpty(checkFullBuyGift.getParticipateActivityResponseList())) {
            return checkFullBuyGift;
        }


        Map<String, String> map = new HashMap<>();
        //移除重复的查询活动请求数据
        activityInfoRequestList = removeRepeatActivityInfoRequest(activityInfoRequestList);

        //查询活动请求封装
        queryActivityRequest.setActivityInfoRequestList(activityInfoRequestList);
        Map<String, String> features = new HashMap<>();
        features.put(CODE_FLAG, OUT_CODE_TO_INNER_CODE);
        queryActivityRequest.setFeatures(features);
        //添加活动查询参数
        map.put(ADD_ACTIVITY_QUERY_PARAM, JSONObject.toJSONString(queryActivityRequest));

        //内外码转换
        map.put(CODE_FLAG, OUT_CODE_TO_INNER_CODE);
        //预报订单号
        map.put(FORECAST_ORDER_BIZ_ID, forecastOrderSDO.getOrderBizId());
        //设置 feature
        participateActivityRequest.setFeatures(map);

        //设置参加活动参数列表
        participateActivityRequest.setParticipateActivityInfoList(participateActivityInfoList);
        //列表为空，不要调用
        if (CollectionUtils.isEmpty(participateActivityInfoList)) {
            ParticipateInActivityResponse participateInActivityResponse = new ParticipateInActivityResponse();
            isNeedCallParticipateActivity[0] = false;
            return participateInActivityResponse;
        }
        Result<ParticipateInActivityResponse> participateInActivityResponseResult = activityWriteService.participateActivityExpand(participateActivityRequest);
        log.info("participateInActivityResponseResult结果:{}",JSON.toJSONString(participateInActivityResponseResult));
        if (Objects.nonNull(participateInActivityResponseResult)
                && Objects.nonNull(participateInActivityResponseResult.getResult())
                && CollectionUtils.isNotEmpty(participateInActivityResponseResult.getResult().getParticipateActivityResponseList())) {

            if (participateInActivityResponseResult.isSuccess()) {
                return participateInActivityResponseResult.getResult();
            }
        }
        return null;
    }

    //套餐活动前置校验
    private ParticipateInActivityResponse checkFullBuyGift(Map<String, Map<Long, List<ActivitySDO>>> preOccupyActivityCheckMap, List<String> ids) {
        ParticipateInActivityResponse participateInActivityResponse = new ParticipateInActivityResponse();
        List<ParticipateActivityInfoResponse> participateActivityResponseList = new ArrayList<>();

        //按主单分组
        boolean checkFlag = true;
        String checkFlagActivityId = "";
        //检查套餐活动是否全部参与
        boolean checkAllJoinFlag = true;
        String checkAllJoinFlagActivityId = "";
        for (Map.Entry<String, Map<Long, List<ActivitySDO>>> mainOrderActivityMapEntry : preOccupyActivityCheckMap.entrySet()) {
            Map<String, Boolean> activitySelectItemMap = new HashMap<>();

            //子单活动列表map
            Map<Long, List<ActivitySDO>> lineOrderActivityMap = mainOrderActivityMapEntry.getValue();
            //同主单下子单ID集合
            List<String> participateSubIdList = lineOrderActivityMap.keySet().stream().map(String::valueOf).collect(Collectors.toList());

            for (Map.Entry<Long, List<ActivitySDO>> lineOrderActivityMapEntity : lineOrderActivityMap.entrySet()) {
                List<ActivitySDO> lineActivities = lineOrderActivityMapEntity.getValue();
                for (ActivitySDO activitySDO : lineActivities) {
                    if (Objects.nonNull(activitySDO.getDisableChooseFlag()) && !activitySDO.getDisableChooseFlag() && activitySDO.getIsSelect()) {
                        String activityId = activitySDO.getActivityCode();
                        activitySelectItemMap.put(activityId, true);
                    }
                }
            }
            for (Map.Entry<Long, List<ActivitySDO>> lineOrderActivityMapEntity : lineOrderActivityMap.entrySet()) {
                List<ActivitySDO> lineActivities = lineOrderActivityMapEntity.getValue();
                boolean haveChooseFlag = CollectionUtils.isNotEmpty(Nullable.stream(lineActivities)
                        .filter(o -> Objects.nonNull(o.getDisableChooseFlag())).collect(Collectors.toList()));

                if (haveChooseFlag) {
                    for (ActivitySDO activitySDO : lineActivities) {
                        if (!activitySDO.getIsSelect() && "ZS02".equals(activitySDO.getActivityType())
                                && activitySelectItemMap.containsKey(activitySDO.getActivityCode())
                        ) {
                            checkFlag = false;
                            checkFlagActivityId = activitySDO.getActivityCode();
                        }
                    }
                }
                for (ActivitySDO lineActivity : lineActivities) {
                    if (lineActivity.getIsSelect() && "ZS02".equals(lineActivity.getActivityType())) {
                        if (CollectionUtils.isNotEmpty(lineActivity.getJoinSubOrderIdList())) {
                            if (!participateSubIdList.containsAll(lineActivity.getJoinSubOrderIdList())) {
                                checkAllJoinFlag = false;
                                checkAllJoinFlagActivityId = lineActivity.getActivityCode();
                            }
                        }
                    }
                }

            }
        }

        if (!checkFlag) {
            for (String value : ids) {
                ParticipateActivityInfoResponse infoResponse = new ParticipateActivityInfoResponse();
                infoResponse.setSubOrderId(value);
                infoResponse.setParticipateResult(false);
                infoResponse.setParticipateResultMsg("套餐活动参与子单不能再选择其他搭赠活动!活动ID:" + checkFlagActivityId);
                participateActivityResponseList.add(infoResponse);
            }
        }

        if (!checkAllJoinFlag) {
            for (String value : ids) {
                ParticipateActivityInfoResponse infoResponse = new ParticipateActivityInfoResponse();
                infoResponse.setSubOrderId(value);
                infoResponse.setParticipateResult(false);
                infoResponse.setParticipateResultMsg("套餐活动参与子单未全部参与!活动ID:" + checkAllJoinFlagActivityId);
                participateActivityResponseList.add(infoResponse);
            }
        }


        participateInActivityResponse.setParticipateActivityResponseList(participateActivityResponseList);
        return participateInActivityResponse;
    }

    /**
     * 更新成最新的活动版本号
     *
     * @param activitySDOS   活动列表，经过分析后的活动列表
     * @param activityCode   活动 ID
     * @param activityTermId 活动项目 ID
     * @param version        活动版本号
     * @return 活动版本号
     */
    private Integer updateNewVersion(List<ActivitySDO> activitySDOS, String activityCode, String activityTermId,
                                     Integer version) {
        if (CollectionUtils.isEmpty(activitySDOS) || StringUtils.isBlank(activityCode)
                || StringUtils.isBlank(activityTermId)) {
            return version;
        }

        Map<String, ActivitySDO> activitySDOMap = activitySDOS.stream().collect(Collectors.toMap(
                sdo -> sdo.getActivityCode() + "_" + sdo.getActivityTermid(), Function.identity()));

        String key = activityCode + "_" + activityTermId;
        if (Objects.nonNull(activitySDOMap.get(key))) {
            return activitySDOMap.get(key).getVersion();
        }
        return version;
    }

    /**
     * 移除重复的子单请求参数
     *
     * @param activityInfoRequestList 查询活动信息请求列表
     * @return
     */
    private List<ActivityInfoRequest> removeRepeatActivityInfoRequest(List<ActivityInfoRequest> activityInfoRequestList) {
        List<ActivityInfoRequest> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(activityInfoRequestList)) {
            return result;
        }

        Map<String, ActivityInfoRequest> map = new HashMap<>();
        for (ActivityInfoRequest infoRequest : activityInfoRequestList) {
            String key = infoRequest.getMainOrderId() + "_" + infoRequest.getSubOrderId();
            map.putIfAbsent(key, infoRequest);
        }

        return new ArrayList<>(map.values());
    }

    /**
     * 构造活动参加参数
     *
     * @param forecastOrderLineSDO
     * @param activitySDO
     * @return
     */

    @NotNull
    private ParticipateActivityInfoRequest buildParticipateActivityInfoRequest(ForecastOrderLineSDO forecastOrderLineSDO, ActivitySDO activitySDO, String sequenceNo,boolean isOrderCenter) {
        ParticipateActivityInfoRequest participateActivityInfoRequest = new ParticipateActivityInfoRequest();
        participateActivityInfoRequest.setActivityId(activitySDO.getActivityCode());
        participateActivityInfoRequest.setClientId(this.forecastOrderSDO.getCustomerCode());
        participateActivityInfoRequest.setMainOrderId(forecastOrderLineSDO.getMainOrderId());
        participateActivityInfoRequest.setSubOrderId(String.valueOf(forecastOrderLineSDO.getId()));
        participateActivityInfoRequest.setOrderType(forecastOrderSDO.getOrderType());
        participateActivityInfoRequest.setDeliveryDate(forecastOrderSDO.getCustomerExpectTDate());
        participateActivityInfoRequest.setActivityUseTime(new Date());
        ParticipateActivityTermRequest participateActivityTermRequest = new ParticipateActivityTermRequest();
        participateActivityTermRequest.setActivityTermId(activitySDO.getActivityTermid());
        participateActivityTermRequest.setSpecialOfferPrice(activitySDO.getSpecialOfferPrice());
        participateActivityTermRequest.setCommonGroupFlag(activitySDO.getCommonGroupFlag());
        participateActivityInfoRequest.setSequenceNo(sequenceNo);
        Map<String, String> features = new HashMap<>();
        //预报订单号
        features.put(FORECAST_ORDER_BIZ_ID, forecastOrderSDO.getOrderBizId());
        //行号
        features.put(SERIAL_NUMBER, forecastOrderLineSDO.getSerialNumber());
        //是否不需要计算赠品金额
        if (Objects.nonNull(activitySDO.getDisableChooseFlag()) && activitySDO.getDisableChooseFlag()) {
            features.put(ACTIVITY_GIFT_HAVE_FEE, Boolean.TRUE.toString());
        }

        participateActivityInfoRequest.setFeatures(features);

        //原品信息
        ActivityItemInfo itemActivityItemInfo = new ActivityItemInfo();
        if(isOrderCenter){
            itemActivityItemInfo.setItemId(forecastOrderLineSDO.getScItemOutCode());
        }else {
            itemActivityItemInfo.setItemId(forecastOrderLineSDO.getScItemId());
        }
        Integer itemQuantity = forecastOrderLineSDO.getPredictReplyAmount() == null ? Integer.parseInt(forecastOrderLineSDO.getQuantity()) :
                forecastOrderLineSDO.getPredictReplyAmount();
        itemActivityItemInfo.setItemQuantity(itemQuantity);
        itemActivityItemInfo.setItemName(forecastOrderLineSDO.getScItemTitle());
        itemActivityItemInfo.setItemPrice(Long.parseLong(String.valueOf(forecastOrderLineSDO.getUnitPrice() == null ? "0" : forecastOrderLineSDO.getUnitPrice())));
        itemActivityItemInfo.setSalesUnit(forecastOrderLineSDO.getSaleUnitCode());
        itemActivityItemInfo.setStockUnit(forecastOrderLineSDO.getInventoryUnit());
        participateActivityTermRequest.setItem(itemActivityItemInfo);
        participateActivityTermRequest.setVersion(activitySDO.getVersion());

        //赠品信息
        List<ActivityItemInfo> giftList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(activitySDO.getChooseGiftList())) {
            activitySDO.getChooseGiftList().forEach(giftSDO -> {
                ActivityItemInfo activityItemInfo = new ActivityItemInfo();
                activityItemInfo.setItemPrice(giftSDO.getGiftPrice());
                activityItemInfo.setItemId(giftSDO.getScItemId());
                activityItemInfo.setItemName(giftSDO.getGiftName());
                activityItemInfo.setItemQuantity(giftSDO.getGiftNumber());
                activityItemInfo.setSalesUnit(giftSDO.getGiftSalesUnitCode());
                activityItemInfo.setItemPrice(giftSDO.getGiftPrice());
                activityItemInfo.setDisableChooseFlag(giftSDO.getGiftDisable());
                giftList.add(activityItemInfo);
            });
        }

        participateActivityTermRequest.setGiftList(giftList);
        participateActivityInfoRequest.setParticipateActivityTermRequest(participateActivityTermRequest);
        return participateActivityInfoRequest;
    }

    @NotNull
    private ParticipateActivityInfoRequest buildSyncParticipateActivityInfoRequest(ForecastOrderLineSDO forecastOrderLineSDO, ActivitySDO activitySDO, String sequenceNo) {
        ParticipateActivityInfoRequest participateActivityInfoRequest = new ParticipateActivityInfoRequest();
        participateActivityInfoRequest.setActivityId(activitySDO.getActivityCode());
        participateActivityInfoRequest.setClientId(this.forecastOrderSDO.getCustomerCode());
        participateActivityInfoRequest.setMainOrderId(forecastOrderLineSDO.getMainOrderBizId());
        participateActivityInfoRequest.setSubOrderId(forecastOrderLineSDO.getMainOrderBizId()+"-"+forecastOrderLineSDO.getSerialNumber());
        participateActivityInfoRequest.setOrderType(forecastOrderSDO.getOrderType());
        participateActivityInfoRequest.setDeliveryDate(forecastOrderSDO.getCustomerExpectTDate());
        participateActivityInfoRequest.setActivityUseTime(new Date());
        ParticipateActivityTermRequest participateActivityTermRequest = new ParticipateActivityTermRequest();
        participateActivityTermRequest.setActivityTermId(activitySDO.getActivityTermid());
        participateActivityTermRequest.setSpecialOfferPrice(activitySDO.getSpecialOfferPrice());
        participateActivityTermRequest.setCommonGroupFlag(activitySDO.getCommonGroupFlag());
        participateActivityInfoRequest.setSequenceNo(sequenceNo);
        Map<String, String> features = new HashMap<>();
        //预报订单号
        features.put(FORECAST_ORDER_BIZ_ID, forecastOrderSDO.getOrderBizId());
        //行号
        features.put(SERIAL_NUMBER, forecastOrderLineSDO.getSerialNumber());
        //是否不需要计算赠品金额
        if (Objects.nonNull(activitySDO.getDisableChooseFlag()) && activitySDO.getDisableChooseFlag()) {
            features.put(ACTIVITY_GIFT_HAVE_FEE, Boolean.TRUE.toString());
        }

        participateActivityInfoRequest.setFeatures(features);

        //原品信息
        ActivityItemInfo itemActivityItemInfo = new ActivityItemInfo();
        itemActivityItemInfo.setItemId(forecastOrderLineSDO.getScItemOutCode());
        Integer itemQuantity = forecastOrderLineSDO.getPredictReplyAmount() == null ? Integer.parseInt(forecastOrderLineSDO.getQuantity()) :
                forecastOrderLineSDO.getPredictReplyAmount();
        itemActivityItemInfo.setItemQuantity(itemQuantity);
        itemActivityItemInfo.setItemName(forecastOrderLineSDO.getScItemTitle());
        itemActivityItemInfo.setItemPrice(Long.parseLong(String.valueOf(forecastOrderLineSDO.getUnitPrice() == null ? "0" : forecastOrderLineSDO.getUnitPrice())));
        itemActivityItemInfo.setSalesUnit(forecastOrderLineSDO.getSaleUnitCode());
        itemActivityItemInfo.setStockUnit(forecastOrderLineSDO.getInventoryUnit());
        participateActivityTermRequest.setItem(itemActivityItemInfo);
        participateActivityTermRequest.setVersion(activitySDO.getVersion());

        //赠品信息
        List<ActivityItemInfo> giftList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(activitySDO.getChooseGiftList())) {
            activitySDO.getChooseGiftList().forEach(giftSDO -> {
                ActivityItemInfo activityItemInfo = new ActivityItemInfo();
                activityItemInfo.setItemPrice(giftSDO.getGiftPrice());
                activityItemInfo.setItemId(giftSDO.getScItemId());
                activityItemInfo.setItemName(giftSDO.getGiftName());
                activityItemInfo.setItemQuantity(giftSDO.getGiftNumber());
                activityItemInfo.setSalesUnit(giftSDO.getGiftSalesUnitCode());
                activityItemInfo.setItemPrice(giftSDO.getGiftPrice());
                activityItemInfo.setDisableChooseFlag(giftSDO.getGiftDisable());
                giftList.add(activityItemInfo);
            });
        }

        participateActivityTermRequest.setGiftList(giftList);
        participateActivityInfoRequest.setParticipateActivityTermRequest(participateActivityTermRequest);
        return participateActivityInfoRequest;
    }

    public List<String> totalReplyNumber() {
        List<String> ids = new ArrayList<>();
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        forecastOrderLineSDOList.forEach(forecastOrderLineSDO -> {
            String id = String.valueOf(forecastOrderLineSDO.getId());
            ids.add(id);
        });
        return ids;
    }

    public boolean confirmForecastStatus() {
        /**
         * 修改订单状态  根据确认数量  修改累计回复数量  判断累计回复数量是否大于预保数量
         * 大于子订单状态变为已完成
         * 不大于子订单状态为部分回复
         *
         * 再根据主单的所有子单状态判断主订单的状态 并作修改
         */
        boolean isSuccess = true;
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            Integer actualTotalReplyAmount = forecastOrderLineSDO.getActualTotalReplyAmount();
            //当累计回复数量大于预保数量的时候状态为已完成 否则为部分回复
            if (actualTotalReplyAmount >= Integer.parseInt(forecastOrderLineSDO.getQuantity())) {
                forecastOrderLineSDO.setStatus(ForecastStatusEnum.COMPLETED.getNumValue());
            } else {
                forecastOrderLineSDO.setStatus(ForecastStatusEnum.PARTIAL_REPLY.getNumValue());
            }
            forecastOrderLineSDO.setPredictReplyAmount(0);
            forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.CONFIRM_ED.getStatus());
            isSuccess = forecastOrderLineWriteRepository.update(forecastOrderLineSDO);
            //添加到处理队列
            updateDealQueueStatus(forecastOrderLineSDO);
        }
        //获取主订单下所有的子订单
        ForecastOrderSDO forecastOrderSDO = forecastOrderLineQueryRepository.queryByOrderId(this.forecastOrderSDO);
        boolean isStatusTag = true;
        int isComTag = 0;
        int isWaitTag = 0;
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderSDO.getForecastOrderLineSDOList()) {
            if (ForecastLineStatusEnum.PARTIAL_REPLY.equals(ForecastLineStatusEnum.of(forecastOrderLineSDO.getStatus()))) {
                forecastOrderSDO.setStatus(ForecastStatusEnum.PARTIAL_REPLY.getNumValue());
                isStatusTag = false;
            }
            if (ForecastLineStatusEnum.COMPLETED.equals(ForecastLineStatusEnum.of(forecastOrderLineSDO.getStatus()))) {
                //子订单有完成状态
                isComTag += 1;
            }
            if (ForecastLineStatusEnum.WAITING_FOR_REPLY.equals(ForecastLineStatusEnum.of(forecastOrderLineSDO.getStatus()))) {
                //子订单有待回复状态
                isWaitTag += 1;
            }
            if (isComTag > 0 && isWaitTag > 0) {
                forecastOrderSDO.setStatus(ForecastStatusEnum.PARTIAL_REPLY.getNumValue());
                isStatusTag = false;
            }
        }
        if (isStatusTag) {
            forecastOrderSDO.setStatus(ForecastStatusEnum.COMPLETED.getNumValue());
        }

        isSuccess = forecastOrderWriteRepository.modifyForecast(forecastOrderSDO);
        return isSuccess;
    }


    /**
     * 更新预报单
     *
     * @return
     */
    public Boolean updateActivityForecast() {
        boolean isSuccess = true;
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            isSuccess = forecastOrderLineWriteRepository.update(forecastOrderLineSDO);
        }
        return isSuccess;
    }

    public Boolean deleteActivityForecast() {
        boolean isSuccess = true;
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            isSuccess = forecastOrderLineWriteRepository.updateForAnalysis(forecastOrderLineSDO);
        }
        return isSuccess;
    }

    public String summaryForecastOrder() {
        //创建调拨单
        AllocateOrderManualCreateRequest createRequest = new AllocateOrderManualCreateRequest();
        createRequest.setType("2");
        createRequest.setReturnOrder(false);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(this.forecastOrderSDO.getCustomerExpectTDate());
        createRequest.setExpectedDeliveryTime(format);
        //总部渠道编码 默认20
        createRequest.setSapChannel("20");
        //总部组织编码 默认6000
        createRequest.setSapSalesOrgId("6000");
        createRequest.setReceiveAreaId(forecastOrderSDO.getWareHouseCode());
        createRequest.setShipMethod(forecastOrderSDO.getTransportModeCode());
        createRequest.setCustomerAddress(forecastOrderSDO.getReceiveDetailAddress());
        createRequest.setIsDTC(false);
        createRequest.setApplyOrgId(forecastOrderSDO.getOrganizationCode());
        createRequest.setRemark("预报生成调拨单");
        Result<AllocateOrderResponse> createResult = allocateOrderWriteService.manualCreate(createRequest);
        if (createResult == null || !createResult.isSuccess() || createResult.getResult() == null) {
            throw new RuntimeException("创建调拨主单失败");
        }
        String id = createResult.getResult().getId();
        String code = createResult.getResult().getCode();

        //保存调拨单明细
        AllocateOrderSaveRequest saveRequest = new AllocateOrderSaveRequest();
        saveRequest.setId(id);
        saveRequest.setCode(code);
        int num = 1;
        List<AllocateOrderScItemDetail> allocateOrderScItemDetails = new ArrayList<>();
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = forecastOrderSDO.getForecastOrderLineSDOList();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            //设置货品信息
            AllocateOrderScItemDetail allocateOrderScItemDetail = new AllocateOrderScItemDetail();
            if (MapUtils.isNotEmpty(forecastOrderLineSDO.getFeatures())) {
                Map features = forecastOrderLineSDO.getFeatures();
                allocateOrderScItemDetail.setScItemId((String) features.get("goodsCode"));
            }
            allocateOrderScItemDetail.setTitle(forecastOrderLineSDO.getScItemTitle());
            allocateOrderScItemDetail.setGoodsId(forecastOrderLineSDO.getScItemId());
            allocateOrderScItemDetail.setUnitPrice(BigDecimal.valueOf(forecastOrderLineSDO.getUnitPrice()));
            allocateOrderScItemDetail.setLineNo(String.valueOf(num++));
            allocateOrderScItemDetail.setApplyQuantity(forecastOrderLineSDO.getQuantity());
            allocateOrderScItemDetail.setConfirmedQuantity(forecastOrderLineSDO.getQuantity());
            allocateOrderScItemDetails.add(allocateOrderScItemDetail);
        }
        saveRequest.setAllocateOrderScItemDetails(allocateOrderScItemDetails);
        log.info("allocateOrderWriteService#saveRequest={}", JSON.toJSONString(saveRequest));
        Result<AllocateOrderSaveResponse> saveResult = allocateOrderWriteService.save(saveRequest);
        if (saveResult == null || !saveResult.isSuccess()) {
            throw new RuntimeException("保存调拨单明细失败");
        }
        return code;
    }

    public ForecastOrderLineSDO getOrderLineFeatures(ForecastOrderLineSDO forecastOrderLineSDO, Integer qty) {
        // 活动价格备注字段
//        if (StringUtils.isEmpty(forecastOrderLineSDO.getActivityPriceRemark()) && CollectionUtils.isNotEmpty(forecastOrderLineSDO.getSaleUnitList())) {
//            return forecastOrderLineSDO;
//        }
        List<String> ids = new ArrayList<>(1);
        ids.add(String.valueOf(forecastOrderLineSDO.getId()));
        Map newLineFeature = forecastOrderLineSDO.getFeatures();
        PageResult<List<ForecastOrderLineSDO>> result = forecastOrderLineQueryRepository.batchLoadList(ids);
        if (CollectionUtils.isEmpty(result.getContent())) {
            return forecastOrderLineSDO;
        }
        Map<String, Object> features = result.getContent().get(0).getFeatures();
        if (MapUtils.isEmpty(features)) {
            Map<String, Object> map = new HashMap<>();
            if (StringUtils.isNotBlank(forecastOrderLineSDO.getActivityPriceRemark())) {
                map.put(ForecastConstants.ACTIVITY_PRICE_REMARK, forecastOrderLineSDO.getActivityPriceRemark());
            }
            if (CollectionUtils.isNotEmpty(forecastOrderLineSDO.getSaleUnitList())) {
                map.put(ForecastConstants.SALE_UNIT_LIST, forecastOrderLineSDO.getSaleUnitList());
            }
            forecastOrderLineSDO.setFeatures(map);
        } else {
            if (StringUtils.isNotBlank(forecastOrderLineSDO.getActivityPriceRemark())) {
                features.put(ForecastConstants.ACTIVITY_PRICE_REMARK, forecastOrderLineSDO.getActivityPriceRemark());
            }
            if (CollectionUtils.isNotEmpty(forecastOrderLineSDO.getSaleUnitList())) {
                features.put(ForecastConstants.SALE_UNIT_LIST, forecastOrderLineSDO.getSaleUnitList());
            }
            if (MapUtils.isNotEmpty(newLineFeature)&&newLineFeature.containsKey(ForecastConstants.ACTIVITY_NUMBER)){
                features.put(ForecastConstants.ACTIVITY_NUMBER,newLineFeature.get(ForecastConstants.ACTIVITY_NUMBER));
            }
            forecastOrderLineSDO.setFeatures(features);
        }
        features.put(DISINTEGRATION_QTY, qty);
        log.info("编辑子单信息:" + JSONObject.toJSONString(forecastOrderLineSDO));
        return forecastOrderLineSDO;
    }

    private Map<String, Object> queryDailyInv(ForecastOrderSDO sdo, ForecastOrderLineSDO build) {
        HashMap<String, Object> stringObjectHashMap = new HashMap<>();

        String organizationCode = sdo.getOrganizationCode();
        String channelCode = sdo.getChannelCode();
        String departmentCode = sdo.getDepartmentCode();
        String salesmanCode = sdo.getSalesmanCode();
        String wareHouseCode = sdo.getWareHouseCode();

        QueryAllotRequest queryAllotRequest = new QueryAllotRequest();
        queryAllotRequest.setOrganizationCode(organizationCode);
        queryAllotRequest.setChannelCode(channelCode);
        queryAllotRequest.setDepartmentCode(departmentCode);
        queryAllotRequest.setSalesmanCode(salesmanCode);
        queryAllotRequest.setWarehouseCode(wareHouseCode);
        queryAllotRequest.setScItemId(build.getScItemId());
        Result<QueryAllotResponse> result = inventoryAllotQueryService.queryAllot(queryAllotRequest);
        stringObjectHashMap.put("limitSwitch", false);
        if (Objects.nonNull(result) && Objects.nonNull(result.getResult())) {
            stringObjectHashMap.put("limitSwitch", result.getResult().getMainLimitSwitch());
            stringObjectHashMap.put("dailyInventory", result.getResult().getRemainingQuantity());
        }
        return stringObjectHashMap;
    }
}
